Pass variable from client to server-side in NEXTJS - next.js

I have already done this but Idk why when I try to apply it again in another code it does not work. So I have this code "Client side"
const response = await fetch("/api/ipfs", {method: "POST", DATA: "holaaaa"});
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const result = await response.json()
console.log(result.result)
And this one that is the "Server side"
function uploadIPFS(req, res) {
axios.get(req.body).then(r => {
let metadata = r.data
res.status(200).json({ metadata: metadata });
}).catch(err => console.error(err))
}
export default function handler(req, res) {
if (req.method==='POST') {
uploadIPFS(req, res);
}
}
This is working with another api file I have, so I implement another file that is this one and in another function of the client side make a call to the new api file, the problem is that the variable I want to pass from client to server is the body one, the one that says "holaaaa", is it not working and it throws this error.
API resolved without sending a response for /api/ipfs, this may result in stalled requests.
Error: Cannot read properties of null (reading 'replace')
at dispatchHttpRequest (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\adapters\http.js:161:23)
at new Promise (<anonymous>)
at httpAdapter (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\adapters\http.js:49:10)
at dispatchRequest (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\dispatchRequest.js:58:10)
at Axios.request (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\Axios.js:109:15)
at Axios.<computed> [as get] (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\Axios.js:131:17)
at Function.wrap [as get] (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\helpers\bind.js:9:15)
at uploadIPFS (webpack-internal:///(api)/./pages/api/ipfs.js:17:11)
at handler (webpack-internal:///(api)/./pages/api/ipfs.js:37:9)
at Object.apiResolver (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\next\dist\server\api-utils\node.js:184:15) {
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.27.2'
},
method: 'get',
url: '',
data: undefined
},
url: '',
exists: true
}
any idea abt this?

The request to your API is made, but you are not adding anything to the request body. I think you need to change your DATA property in your fetch call to body:
const response = await fetch("/api/ipfs", { method: "POST", body: "holaaaa" });
Also, since you are passing that body parameter to the axios.get() method in your API handler, I assume it's supposed to be a URL?

Related

FastAPI and Axios POST request misconfiguration

I have a FastAPI backend configured as such:
#app.post("/engines/completions")
async def read_completions(
# engine_id:str,
prompt: Optional[str] = None,
max_tokens: Optional[int] = 16,
temperature: Optional[float] = 1.0,
top_p: Optional[float] = 1.0,
top_k: Optional[int] = 40,
n: Optional[int] = 1,
stream: Optional[bool] = False,
logprobs: Optional[int] = None,
echo: Optional[bool] = False,
stop: Optional[list] = None,
presence_penalty: Optional[float] = 0.0001,
frequency_penalty: Optional[float] = 0.0001,
best_of: Optional[int] = 1,
recursive_depth: Optional[int] = 0,
recursive_refresh: Optional[int] = 0,
logit_bias: Optional[Dict[str, float]] = None,
):
and an Axios request configured like this:
let stop = "stuff";
let prompt ="test";
let url = "http://localhost:8000/engines/completions";
const options = {
method: "POST",
headers: { "content-type": "application/json"},
timeout: 2000000,
body: {stop, prompt},
url,
};
axios(options)
My request goes through without getting a 442 error, but prompt and stop attributes would result in None in my read_completions function. What am I doing wrong?
Use data instead of body on your axios' options.
See Request Config on axios documentation,
My request will go through without a 442
Your request goes through, as all parameters are defined as optional. Thus, not receiving these parameters, the server won't complain.
but prompt and stop will evaluate as None in my read_completions
function.
They are both None (null), as the server never received any values for them. Your endpoint expects these parameters being Query parameters, however, your client sends (or actually, attempts to send) body parameters.
Option 1
Adjust your endpoint to expect Form data. Also, if you are going to define a parameter to be a List, please have a look at this on how to do that properly.
from typing import Optional, List
#app.post("/engines/completions")
def read_completions(
prompt: Optional[str] = Form(None),
stop: Optional[List[str]] = Form(None)
):
return {"prompt": prompt, "stop list": stop}
Then, your client side should look like this:
function uploadFormData() {
var formData = new FormData();
var alphaArray = ['A', 'B', 'C','D','E'];
for (var i = 0; i < alphaArray.length; i++) {
formData.append('stop', alphaArray [i]);
}
formData.append("prompt", "test");
axios({
method: 'post',
url: '/engines/completions',
data: formData,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
}
Option 2
Adjust your endpoint to expect JSON (body) parameters. In FastAPI, you could do that using either Body parameters or Pydantic models. The example below uses the latter.
from pydantic import BaseModel
from typing import Optional, List
class Item(BaseModel):
prompt: str = None
stop: Optional[List[str]] = None
#app.post("/engines/completions")
def read_completions(item: Item):
return {"prompt": item.prompt, "stop list": item.stop}
Finally, the client side should look like the below:
function uploadJSONdata() {
axios({
method: 'post',
url: '/engines/completions',
data: JSON.stringify({"prompt": "test", "stop": ['A', 'B', 'C','D','E']}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
}

getting error responses from nft.storage's /store API endpoint using fetch

let formData = new FormData();
formData.append("name",name);
formData.append("description",description);
formData.append("image", image);
fetch("https://api.nft.storage/store",{
method: "POST",
body: formData,
headers: {
'Authorization': 'Bearer '+process.env.TEST_API_KEY,
}
}).then(response => response.json())
.then((json)=>{
console.log(json)
})
This is what I've been trying to do but keep getting error as a response. Errors are usually invalid-file or something to do with content-type.
https://nft.storage/api-docs/ - This is the api documentation. If theres any example for the same, it'll be really helpful. Thanks!
Long time since question... just for any one wondering:
The api endpoint receives 1 parameter called meta which is a json_encoded representation of the fields, any falsy value like image: undefined, will be replaced with an extra field you must include, with the binary representation of the field... here is an example:
let params = {
name: 'name of the nft',
image: undefined,
description: 'description of the nft'
}
let formData = new FormData();
formData.append("meta",JSON.stringify(params));
formData.append("image",new File([ someBinaryImageData ], 'nft.png', { type: 'image/png' });
fetch("https://api.nft.storage/store",{
method: "POST",
body: formData,
headers: {
'Authorization': 'Bearer '+process.env.TEST_API_KEY,
}
})
.then(response => response.json())
.then((json)=>{
console.log(json);
})

ClientFunction: _axios2 is not defined

I'm running TestCafe for UI automation, using ClientFunctions to trigger API requests (so that I can pass along session cookies).
Currently I have a ClientFunction with fetch which works fine... except we're now testing IE 11 and Fetch is unsupported.
Fetch code:
const fetchRequestClientFunction = ClientFunction((details, endpoint, auth, method) => {
return window
.fetch(endpoint, {
method,
credentials: 'include',
headers: new Headers({
accept: 'application/json',
'Content-Type': 'application/json',
}),
body: JSON.stringify(details),
})
.then(httpResponse => {
if (httpResponse.ok) {
return httpResponse.json();
}
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
However when I try to switch it to axios... not so much:
import axios from 'axios';
const axiosRequest = ClientFunction((details, endpoint, auth, method) => {
return axios({
method,
auth,
url: endpoint,
data: details,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
timeout: 3000,
})
.then(httpResponse => {
if (httpResponse.status < 300) return httpResponse;
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
Tried using window.axios, and also passing axios as a dependency. I've also tried making the axios request without the ClientFunction... and despite getting response of 200, the website wasn't updated as expected.
Each time I either get _axios2 is not defined or window.axios is not a function. I would greatly appreciate some guidance here.
TestCafe ClientFunctions allow only serializable objects as dependencies. You need to have axios on the client side to send such a request.

linkedin API cannot create campaign

We have got rw_ads permissions for an app. Through that app We have taken access_token with all given permissions.
As mentioned in the documentation, we have rw_ads permission, but If we try to create/update campaign we are getting the below error.
{
"serviceErrorCode": 100,
"message": "Not enough permissions to access: POST /adCampaignsV2/sdafnk",
"status": 403 }
var request = require("request");
var options = { method: 'POST',
url: 'https://api.linkedin.com/v2/adCampaignsV2/sdafnk',
headers:
{ 'Authorization': 'Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Type': 'application/json' },
body:
{ patch:
{ '$set':
{ runSchedule: { end: 1548405000000, start: 1547713800000 },
status: 'ACTIVE' } } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Code for creation of campaign is mentioned below
var request = require("request");
var options = {
method: 'POST',
url: 'https://api.linkedin.com/v2/adCampaignsV2',
headers: {
'Authorization': 'Bearer <accessToken>',
'Content-Type': 'application/json'
},
body: {
account: 'urn:li:sponsoredAccount:<accountId>',
audienceExpansionEnabled: false,
costType: 'CPM',
creativeSelection: 'OPTIMIZED',
dailyBudget: { amount: '200', currencyCode: 'INR' },
locale: { country: 'IN', language: 'en' },
name: 'Campaign text ad test',
objectiveType: 'WEBSITE_TRAFFIC',
offsiteDeliveryEnabled: false,
runSchedule: { end: 1547708400000, start: 1547967600000 },
type: 'TEXT_AD',
unitCost: { amount: '10', currencyCode: 'INR' },
status: 'PAUSED'
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
When you perform a partial update, the header X-RestLi-Method must be included in the request and set to PARTIAL_UPDATE.
Also if you use implicit grant-type, check if you have defined the scope correctly at the start. if you use client-credentials grant-type check if the account has the right permissions.
Direct Sponsored Content can be created by:
Ad Account Users with a role higher than VIEWER. Organization users
with DIRECT_SPONSORED_CONTENT_POSTER or ADMINISTRATOR roles.
also the code you added in this question is for Reactivating a campaign. not for updating/creating one.

Symfony3 / Nelmio cors / fetch api — 400 Bad Request

As the title says, I have a symfony3 Application with a rest api on a subdomain so that:
GET http://ajax.localhost.dev:10190/menus
returns a list of menus in JSON format.
Here is the configuration of the nelmio cors bundle (/app/config/nelmio/cors.yml)
nelmio_cors:
paths:
'^/':
origin_regex: true
allow_origin: ['^https?://%domain%:[0-9]+']
allow_headers: ['X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
max_age: 3600
hosts: ['^ajax\.']
allow_credentials: true
I have been using this code:
export default class AppRemote extends Remote {
get host () { return `ajax.${super.host}`; }
open(xhr, data) {
if ("withCredentials" in xhr) {
xhr.open(data.method, this.url(data.url), true);
xhr.withCredentials = true; }
else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(data.method, this.url(data.url)); }
else { this.app.error('cannot init CORS Request'); }
return xhr;
}
};
which was working fine. Now I am trying to port it to the new fetch API and I am using this code:
const init = (url, method = 'GET') => {
return new Request(url, {
headers: new Headers({
'Access-Control-Allow-Credentials': true,
//'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
}),
mode: 'cors',
credentials: true,
method });
}
const get = (url) => {
return fetch(init(url));
}
It returns a 400 Bad Request, with Request Method: OPTIONS. If I just type the url in the browser, it works.
I guess there is some authentication issue, but just cannot figure out how to solve it. How can I do that?
After some research I finally found the mistake. Thanks to Firefox, which threw an error pointing me to the spot:
return new Request(url, {
//headers: new Headers({
//'Access-Control-Allow-Credentials': true,
//'Access-Control-Allow-Origin': '*',
//'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
//}), //<-- working without headers at all
mode: 'cors',
credentials: 'include', //<-- that is the right setting
method });
Docs on MDN

Resources