Nodejs create diffrent post request - javascript

I’ve the following code which works when using standalone request (not promise all) , but I don’t know how can I send two request with different form data properties (see aaaa/bbbb exmaple)
e.g. this is what I need to pass for the first request (different scope)
formData.append('grant_type', 'client_credentials');
formData.append('scope', ‘aaaa’);
And this is to the second request (in the promise all)
formData.append('grant_type', 'client_credentials');
formData.append('scope', ‘bbbbb');
This is the code:
let [res1,res2] = await Promise.all([axios({
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]',
...formData.getHeaders()
},
data: formData
},
{
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]’,
...formData.getHeaders()
},
data: formData
}
)])
console.log(res1.data.access_token)
Could I append it inline for each request? I try to put an object with those properties and it doesn't compile
is there a way to do something like this
{
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]’,
...formData.getHeaders()
},
data: formData.append([{
'grant_type': 'client_credentials'
},{
'scope': 'aaaa`
}])
}
update:
I've tried to do something like
let [res1, res2] = await Promise.all([
axios({
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]',
...formA.getHeaders()
},
data: formA
}),
axios({
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]',
...formB.getHeaders()
},
data: formB
})
])
console.log(res1.data.access_token)
function formA() {
formData.append('grant_type', 'client_credentials');
formData.append('scope', 'aaaa');
return formData
}
function formB() {
let formData = new FormData();
formData.append('grant_type', 'client_credentials');
formData.append('scope', 'bbbb');
return formData
}
Which doesn't work, now if I create the object inside like it works but the code is ugly, is there a better way to achieve this
function formB() {
let formData = new FormData();
formData.append('grant_type', 'client_credentials');
formData.append('scope', 'bbbb');
return formData
}

You're nearly there.
The main problem is that the axios function needs to be called multiple times in the Promise.all function.
With the above solved, my last recommendation is to make separate form-data objects for each request.
For example:
var formData1 = getFormDataObjectSomehow()
var formData2 = getAnotherFormDataObjectSomehow()
let [res1, res2] = await Promise.all([
axios({
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]',
...formData1.getHeaders()
},
data: formData1
}),
axios({
method: 'post',
url: 'https://oauth2.md/oauth2/token',
headers: {
'Authorization': 'Basic [userpassword]',
...formData2.getHeaders()
},
data: formData2
})
])
console.log(res1.data.access_token)
EDIT:
And don't forget to handle errors thrown from the axios requests. Either add .catch() block to your Promise.all or use a try/catch guard.

Related

How do you express it using the fetch API in JavaScript?

Now, I POST image data using ajax(jquery) as follows. The image is a File object.
async function postImage({ image }) {
const result = await $.ajax({
method: 'POST',
url: '/api/images',
dataType: 'json',
data: image,
processData: false,
async: true,
headers: {
'Content-Type': 'application/octet-stream',
},
});
return result;
}
The result that return object is {id: imageID}.
How can I express this using the Fetch API? I couldn't get the result even if I did the following.
const result = await fetch('/api/images', {
method: 'POST',
body: image,
headers: {
'Content-Type': 'application/octet-stream',
},
});
return result;
fetch() returns a promise to a Response object, and that has a json() method which returns another promise to the parsed response JSON.
const response = await fetch('/api/images', {
method: 'POST',
body: image,
headers: {
'Content-Type': 'application/octet-stream',
},
});
const result = await response.json();

Javascript Fetch Body JSON List

I am trying to make a post request and getting this exception:
"unsupported BodyInit type"
I think the issue is with the body of the request. phoneNumbers takes on the form phoneNumbers = ["1234567890", "1234567891"] (i.e. a list of strings). I tried to do JSON.stringify(phoneNumbers) as the body, but that seems to return "[]", even if the list is not empty.
export async function findUsersByPhoneNumbersNotFollowing(userId, phoneNumbers) {
const reqConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: phoneNumbers,
};
const response = await authfetch(`${API_URL}/following/recommendations/${userId}`, reqConfig);
if (response.error) {
throw new Error(response.error);
}
return response;
}
Where am I going wrong? The API endpoint is expecting List<String> (using spring framework, and the controller method takes this param in annotated #RequestBody)
Try sending a JSON Object instead a plain array:
const reqConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
paramName: phoneNumbers
}),
};
Replace paramName for the name you are expecting on your API endpoint.

What is best practice for handling axios that sends back no request (no catch or no .then executes)?

I've encountered situations where maybe because of a bad connection where there is no response from the api where it skips both the .then and .catch. What is the best practice for error handling in that case? I'd like to put up an alert if there is no response at all.
const getPic () => {
axios({
url: '/users/avatar',
method: 'GET',
headers: {
'Authorization': "Bearer " + token,
},
data: {avatar: avatarUrl},
responseType: 'blob',
}).then((response) => {
log(response);
let blob = URL.createObjectURL(response.data)
localStorage.setItem('image', blob);
}.catch(error) {
console.log(error)
}
}
You should set a timeout which will cause the promise to reject in the case that there is no response.
axios({
url: '/users/avatar',
method: 'GET',
headers: {
'Authorization': "Bearer " + token,
},
timeout: 1000,
data: {avatar: avatarUrl},
responseType: 'blob',
})
~``

Converting fetch PUT request into axios request

I have been using fetch on the frontend to make a PUT request. My code looked like the following:
fetch(url, {
headers: {
'content-type': 'png',
},
method: 'PUT',
body: file,
})
I am trying to write the same using axios but doesn't seem to be working
await axios.put(url, {
data: {
body: file
},
headers: {
'content-type': 'png',
},
})
Take a look at the axios.put signature:
axios.put(url[, data[, config]])
The second argument is treated as data, so your headers end up as part of the request body.
Further, data: { body: file }, is redundant. axios.put()'s data argument is already treated as body.
So you can either do:
await axios.put(url, file,
{
headers: {
'content-type': 'png'
}
}
)
or:
await axios.put(url, {},
{
data: file,
headers: {
'content-type': 'png'
}
}
)
Or, for even more resemblance with fetch API,
await axios(url,
{
method: 'PUT',
data: file,
headers: {
'content-type': 'png'
}
}
)

call function after multiple loops of fetch()

If i want to call doStuff()
when multiple loops of fetch are finnish, how would i approach it ?
im assuming i need to call a function every time a fetch is done and check if concat of both array length is at the last one ?
let array1 = [1,2]
let array2 = [7,8]
array1.map(function(item){
fetch("/api/execution/"+item, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
});
array2.map(function(item){
fetch("/api/something/"+item, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
});
//call doStuff only when all the fetchs are done
function doStuff(){
console.log("yay")
}
You're using .map() to launch the requests but you're not saving the returned Promise instances.
let p1 = array1.map(function(item){
return fetch("/api/execution/"+item, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
});
And similarly for array2. You can then concatenate the two arrays of Promises and use Promise.all():
let p1 = array1.map(function(item){
return fetch("/api/execution/"+item, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
});
let p2 = array2.map(function(item){
return fetch("/api/something/"+item, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
});
Promise.all(p1.concat(p2)).then(function(fetchedValues) {
// all fetch calls are finished
});

Categories

Resources