Cypress giving error about promise while sending api request - javascript

I got a promise error by cypress; what should I do? What am I missing?
let woID = 0
let woCoordinate = 0
let keyCloakToken = 0
class utils {
createIncidentViaAPI() {
keyCloakToken = localStorage.getItem('keycloak-token')
fetch('https://URL', {
headers: {
accept: 'application/json, text/plain, */*',
authorization: 'Bearer ' + keyCloakToken,
'content-type': 'application/json;charset=UTF-8',
},
body: '{"description":"keycloak","type":"SY","startDate":"2022-08-14T12:19:00.000Z","locationAddress":"Japanese Pagoda Ohio Dr SW","latitude":38.88366120709875,"longitude":-77.04149404953358,"sourceType":"CALL"}',
method: 'POST'
})
.then((res) => res.json())
.then((out) => {
cy.log(out.data.incidentId)
})
}
the fetch request that you can see at the top is working stable without problem but I having some issues to work API request at the bottom.
the important thing is that when I send createWorkOrderViaAPI() request I should have to wait 60-70 seconds because the system responds every 60 secs. That's why I tried to use then block. by the way, I tried some different options too but I didn't solve the promise problem.
createWorkOrderViaAPI() {
cy.request({
url: 'URL',
method: 'POST',
headers: {
properties: 'wonum',
'Content-Type': 'application/json',
MAXAUTH: 'autpassword',
Authorization: 'Basic ' + 'autpassword'
},
body: {
description: 'test request',
}
}).then((res) => {
woID = res.body.wonum
//here i want get some numbers then i want to use these second API request which you can see //inside then block.
}).then((out)=>{
fetch('https://URL', {
headers: {
accept: 'application/json, text/plain, */*',
'accept-language': 'tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7',
authorization: 'Bearer ' + keyCloakToken,
},
body:
'{"statusList":"sortDirection":"DESC","archivalTypeList":["ACTIVE"],"countByField":"NEIGHBORHOOD","searchText":"' +
---> i want use woID number here ---> woID +
'}',
method: 'POST'
}).then((res) => {
woCoordinate = res.body.wkt
cy.log(woCoordinate)
})
})
}
when I run this code i getting error message by cypress about promise I leaving the message doc here
especially when I change cy.request to fetch error just disappears but fetch is not working not creating order as i want.

The problem is that you cant use cy. methods inside of any then block.
.then(()=>{
don't use here any cypress method
})
I separated my own API requests and deleted necessary cypress requests then it worked.

Related

use a specific value from JSON response from GET request via fetch --> to a POST request

the main goal here is to use the part of the response, in the 2nd POST requset.
Let me explain -
given the following endpoint:
https://www.example.com/Applications/?api-version=1&_cacheToken=1675420688869
the response from sending a GET request to the endpoint is :
{"field1":"","Items":[{"Name":"app:\/appname","field2":"appnumber","field3":"appvers","Status":"Ready","Parameters":[],"health":"Ok","kind":"numbers","ids":{"id":[]},"met":{"met1":{}},"Id":"1"}]}
I would like to use only the value of "appname".
hence i'm using it as follows -
---SNIP---
...
.then(data => {
const appname = data.Items[0].Name;
const appname_updated = appname.replace('app:/', '');
...
---SNIP---
I would like to use it with a second fetch request, but this time in a form of POST (in the endpoint itself and in the body):
return fetch('https://www.example.com/deploy/'+appname_updated+'/?api-version=1', {
method: 'POST',
headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json; charset=utf-8' },
mode: 'no-cors',
body: JSON.stringify({
appname: appname_updated,
field1: "blah"
})
});
})
How this can possible be done ? so the first GET will be sent, receieve 200 ok,
and once it got the 200 status, the POST should send right after with the proper
values populated.
No matter what i've tried so far, nothing seems to be send the second POST rquest.
(I've tried it with asyc/wait etc.)
----- update ----
this is the full code -
<script>
const firstUrl = "https://example.com/Applications/?api-version=1";
const secondUrl = "https://example.com/deploy/";
async function fetchData() {
try {
const response = await fetch(firstUrl, {
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json; charset=utf-8'
}
});
if (response.status === 200) {
const data = await response.json();
const appname_updated = data.Items[0].Id;
const secondResponse = await fetch(secondUrl + appname_updated + '/?api-version=1', {
method: "POST",
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify({
appname: appname_updated,
...rest of JSON
})
});
if (secondResponse.status === 200) {
console.log("POST request successful");
} else {
console.error("Error with POST request");
}
} else {
console.error("Error with GET request");
}
} catch (error) {
console.error("Error with fetch: ", error);
}
}
fetchData();
</script>
Thanks
'no-cors' tells fetch to fail silently if you try to do anything which requires permission from CORS.
Making a cross-origin request with 'Content-Type': 'application/json; charset=utf-8' requires permission from CORS.
Don't use 'no-cors'.

POST https://accounts.spotify.com/api/token 415 error when using fetch

I'm trying to make a request to get an authorization code from the spotify api using fetch but I keep getting a 415 error code. I did not have any errors when i was originally using $.ajax instead of fetch.
let client_id = '8f10fa8af1aa40c6b52073811460bf33'
let client_secret = '27a7c01912444b409a7f9a6d1f700868'
let ah = btoa(client_id + ":" + client_secret)
const getAuthToken = (searchedTerm) => {
fetch( `https://accounts.spotify.com/api/token`,
{
headers: {
'Content-Type': 'application/x-www-form-url-encoded',
'Authorization': `Basic ${ah}`
},
body: {
grant_type: 'client_credentials'
},
json: true,
method : "POST"
}
)
.then(function(response) {
authToken = response.access_token;
spotifySearch(response.access_token, searchedTerm);
})
}
See this answer on a similar post. Note that there they set 'Content-Type':'application/x-www-form-urlencoded', with no hyphen between url and encoded. I think you simply need to change
headers: {
'Content-Type': 'application/x-www-form-url-encoded',
'Authorization': `Basic ${ah}`
},
to
headers: {
'Content-Type': 'application/x-www-form-urlencoded', // no hyphen in urlencoded
'Authorization': `Basic ${ah}`
},

React axios put request returns error 500

axios.put('http://1.1.1.1:1010/api/data', {
data: {
ip: '123123',
smth: true
},
headers: {
'content-type': "application/json ",
'Access-Control-Allow-Origin': '*',
},
}).then(res => {
console.log(res)
}).catch(error => {
console.log(error);
})
I recieved
Error: Request failed with status code 500
Get request works fine. I tryed without any success:
headers: {
'content-type': "application/json ",
'Access-Control-Allow-Origin': '*',
},
data: {
ip: '123123',
dhcp: true
},
withCredentials: true,
crossdomain: true,
proxy: {
host: 'http://1.1.1.1',
port: 1010
},
validateStatus: (status) => {
return true;
},
In the backend error on the last line::
json_data = request.get_json(force=True)
accountGuid = 'DummyAccount'
pdict = json_data[self.tableName]
Help me please. I don't understood what I have to do
OK I'm not sure what the logic is behind this but it recently happened to me.
I had a put request that was giving me 500 internal server error but on postman the same request would work fine.
Here is what fixed the issue.
axios has two ways of sending request.
axios.put(url,body,config);
and
axios(request object);
I am sharing my code. May be it helps you as well.
The request was failing at this code.
const { data } = await axios.put(`trainer-schedule/cancel-appointment-student/${id}`, null, {
headers: {
'Authorization': 'Bearer ' + await AsyncStorage.getItem('auth_token'),
'Access-Control-Allow-Origin': '*',
}
});
I just changed it to other way and it started working.
const { data } = await axios({
url: `trainer-schedule/cancel-appointment-student/${id}`,
headers: {
'Authorization': 'Bearer ' + await AsyncStorage.getItem('auth_token'),
'Access-Control-Allow-Origin': '*',
},
method: 'put'
});
My envoirenment is react-native, backend express js.
I would recommend to always test your requests on postman. It is the best tool out there to test apis. but what happened to me is a very rare case.
I hope it helps you.

can't send multipart with fetch but axios works fine

Here is my code:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
body: payload,
});
}
function uploadImage2(payload) {
return axios.post('/api/storage/upload/image/', payload, {
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
});
}
function test(file, meta_data) {
var formBody = new FormData();
formBody.set('image', file);
formBody.set('meta_data', meta_data);
uploadImage(formBody);
// doesn't work
uploadImage2(formBody);
// works
}
Can someone please explain to me how I'm supposed to send multipart requests with fetch?
The error I get with this code is: 400 bad request, file and meta_data are null.
Do not use this header: 'Content-Type': 'multipart/form-data'.
Remove the header and it should work.
Explanation:
When using fetch with the 'Content-Type': 'multipart/form-data' you also have to set the boundary (the separator between the fields that are being sent in the request).
Without the boundary, the server receiving the request won't know where a field starts and where it ends.
You could set the boundary yourself, but it's better to let the browser do that automatically by removing the 'Content-Type' header altogether.
Here's some more insight: Uploading files using 'fetch' and 'FormData'
Here is what worked for me:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
},
body: payload,
});
}
By comparing the cURL requests sent by the browser I discovered that in the axios request has this:
"Content-Type": "multipart/form-data; boundary=---------------------------19679527153991285751414616421",
So I figured that when you manually specify the content type, fetch respects that and doesn't touch anything while still does it's thing the way it wants:-/ so you just shouldn't specify it, fetch will know itself since you are using formData()

Uploading file via PUT method in react-native

I am trying to upload file(image) from my react-native app to backend server. The RESTFUL backend server accepts file send via PUT method on a specific url. I am stuck on react-native trying to find the proper way to send file via PUT method.
I am trying to replicate behavior of
curl -X PUT -T "/path/to/file" "http://myputserver.com/puturl.tmp"
I found XMLHttpRequest method of doing this on a browser but won't work on react-native. Have anyone gone through this please help!!!
fetch('https://mywebsite.com/endpoint/', {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
})
.then((response) => response.json())
.then((responseJson) => {
alert(responseJson)
})
.catch((error) => {
console.error(error)
})
reference
reference 2
Fetch
Use the fetch api, which is supported by React Native.
Below is an example of the official documentation.
Fetch supports PUT, according to the specs.
fetch('https://mywebsite.com/endpoint/', {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
You can use the PUT like the answer above. You might be missing the 'Content-Type': 'multipart/form-data;'.
const config = {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data;',
'Authorization': 'Bearer ' + 'SECRET_OAUTH2_TOKEN_IF_AUTH',
},
body: data,
}
Some more information in this blog post:
http://snowball.digital/Blog/Uploading-Images-in-React-Native

Categories