javascript post fetch request gone wrong - fetch

please, help me check this post request.
I've been looking at it since yesterday, I don't know what is wrong with it
maybe I need another developer's pairs of eyes.
thanks in advance
buttons.addEventListener('click', ()=>{
fetch("https://jsonplaceholder.typicode.com/comments", config)
.then(res=>{
res.json();
}).then(datae=>{
console.log(datae);
})
});
const config = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newName)
}

buttons.addEventListener('click', () => {
fetch('https://jsonplaceholder.typicode.com/comments', config)
.then((res) => {
return res.json()
})
.then((datae) => {
console.log(datae)
})
})
you just need to return res.json()
this should work, but remember that the function you pass to the .then function has access to the returned value from the previous .then.
fetch returns a promise that resolves into an object with the .json function
so in the first .then it will get that object and you need to return res.json() which returns a promise that will be resolved to the JSON data
so in the next .then you can use that data
I hope I was clear
note:
.then function returns a promise ( always )
also maybe you have an error in the config variable, what you pass to the JSON.stringify function should be a valid javascript object
const config = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'rowadz' }),
}

Related

Firebase Callable Function can't return after callback

I'm new in JS world and callbacks.
Why I can't return response after then function for the Firebase callable functions?
It returns empty if I return like shown below. I guess it doesn't wait for the response, response has data.output variable actually.
exports.testApi = functions.https.onCall(async(data, context) => {
const formData = new FormData();
formData.append("height", "512");
const response = await axios.post('https://....', formData, {
headers: formData.getHeaders()
})
.then((response) => {
console.log(response.data);
return {'imageURL':response.data.output};
})
.catch((error) => {
console.log(error)
});
}
);
It works with this format
const response = await axios.post('https://..', formData, {
headers: formData.getHeaders()
})
return {'imageURL':response.data.output};
The main attraction of async and await is cleaner syntax, in particular syntax that doesn't use then (opinion). You can mix them but I would always try to avoid it, especially here where the task is so simple.
exports.testApi = functions.https.onCall(async(data, context) => {
try {
const formData = new FormData();
formData.append("height", "512");
// Wait for post to give us a response.
const response = await axios.post('https://....', formData, {
headers: formData.getHeaders()
});
// If we get here, we waited and got a response. Proceed.
console.log(response.data);
return {'imageURL': response.data.output};
} catch (error) {
// If we get here, post threw an error (assuming it throws).
// And we never executed any lines after const response = await...
console.log(error);
}
});
Side note: Firebase Cloud Functions have to be properly terminated and this function does not. For example, if post throws an error and control flows to the catch block then the function will simply timeout because we haven't returned a Promise or thrown a compliant error.

Cypress API testing. Can not find property

I am developing Cypress tests for my API.
The response from my API in Postman is below:
{"infected" : false}
And my Cypress test is below:
describe("Testing the result after scanning file", () => {
it("Scan file", function () {
//Declarations
const fileName = 'example.json';
cy.fixture(fileName, 'binary')
.then((file) => Cypress.Blob.binaryStringToBlob(file))
.then((blob) => {
const formData = new FormData();
formData.append("file", blob, fileName);
cy.request({
method: 'POST',
headers: {
'content-type': 'multipart/form-data'
},
body: formData,
url: '/scan'
}).then(response => {
console.log('the response is: ', response.body)
expect(response.body).to.have.property('infected').and.eq(false);
});
})
});
});
In my browser, the Cypress test fails with the message:
assert expected {} to have property infected
I really have already broken my brain with this issue and still have no clue how to tackle it. Can anybody give me an idea what is going wrong?
Try converting the response to json, you may be seeing a string version of the data.
Postman output will not be helpful, it could be converting automatically in the background.
cy.request({
...
})
.then(response => response.json())
// OR
// .then(response => response.body.json())
.then(data => {
console.log('the data is: ', data) // better debug tool than Postman
expect(data).to.have.property('infected').and.eq(false);
});

Where is fetch getting it's endpoint value from?

I have the following code, I am using React:
// post-post
const queryDatabase = (obj, endpoint) => {
console.log(obj);
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(obj)
};
console.log(endpoint);
fetch(endpoint, requestOptions)
.then(data => {return Promise.resolve(data)}
);
}
export {queryDatabase};
For some reason console.log(endpoint) prints the endpoint that I am passing in, e.g. "/users", "/profile" etc. However, fetch is trying to send to http://localhost:3000/users so when I try to manually pass in an endpoint I get an error about trying to post to http://localhost/http://localhost/users.
Where is fetch getting this default http://localhost:3000 value?
It's only doing this for POST requests.
The only environment variables are the following:
REACT_APP_AUTH0_REDIRECT_URI=http://localhost:3000
REACT_API_SERVER_URL=http://api.localhost
PORT=3000
I also have some other environment variables for Auth0, is Auth0 doing this? I've removed these variables for testing and still nothing.
The answer is to use the Request object and pass that through to fetch:
const requestOptions = new Request(serverUrl + endpoint, {
method: 'POST',
body: JSON.stringify(obj),
headers: new Headers({
'Content-Type': 'application/json'
})
});
Why bother... use axios or something else, fetch sucks.
EDIT:
Apparently not a problem with fetch. Whatever the case this is the fix.

mystery request proc_name= &params=

Trying to debug a new React-native application -- pretty large and it has no backend so I am trying to stub something out.
The request format is pretty foreign to me. Does anyone recognize this format or know how to handle it?
proc_name=customer_ref&params={"fields" : ["customerId"],"conditions":[{"mailAddress":"dsadsa"},{"pinCode":"ZHNhZHNh"},{"mailReceiveFlag":"1"}],"order" : ["customerCode desc"],"limit" : "1","table_name" : "Customer"}
React-native request code looks like this:
try{
let result = await fetch(apiUrl, {
method: 'POST',
headers: {
'X_contract_id': contact_id,
'X_access_token': access_token,
'Content-Type': 'application/x-www-form-urlencoded',
'charset':'UTF-8',
},
body: 'proc_name='+proc_name+'&params={'+params+'}'
}).then((response) => response.json())
.then((responseJson) => {
return responseJson.result;
})
return result;
}catch(e){
console.log(e);
}
The application errors out with Unhandled Promise Rejection before even making it to the server I whipped up. Pretty new here; am I doing something wrong at the frontend layer?
Try changing your fetch structure to be like this.
async functionName(){
try{
let result = await fetch(apiUrl, {
method: 'POST',
headers: {
'X_contract_id': contact_id,
'X_access_token': access_token,
'Content-Type': 'application/x-www-form-urlencoded',
'charset':'UTF-8',
},
body: 'proc_name='+proc_name+'&params={'+params+'}'
});
let resultjson = await result.json();
return resultjson.result;
}catch(e){
console.log(e);
}
}
https://facebook.github.io/react-native/docs/network.html

Sending data as key-value pair using fetch polyfill in react-native

The following code is to make HTTP POST request with fetch polyfill:
fetch(url, {
method: 'post',
body: JSON.stringify({
token: this.state.token,
}),
})
.then((response) => response.json())
.then((responseData) => {
console.log(responseData);
})
.done();
This request sends data as a stringified JSON obj. Is there a way to send data as key-value pair similar to requests? post(URL, data=payload) in python.
Sounds like you want the same format as a querystring, so import/require a package like https://www.npmjs.com/package/query-string which doesn't appear to depend on any browser features and has a stringify method:
queryString.stringify({
foo: 'bar',
nested: JSON.stringify({
unicorn: 'cake',
}),
});
//=> foo=bar&nested=%7B%22unicorn%22%3A%22cake%22%7D
Alternatively you could just use the relevant part of its source code, though this would still be subject to its license:
function toQueryString(obj) {
return obj
? Object.keys(obj)
.sort()
.map(function (key) {
var val = obj[key];
if (Array.isArray(val)) {
return val
.sort()
.map(function (val2) {
return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
})
.join('&');
}
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
})
.join('&')
: '';
}
You can then use the return value in your body parameter in fetch:
fetch(url, {
method: 'post',
body: toQueryString({ token: this.state.token }),
});
Sure. Look at the fetch documentation in github: https://github.com/github/fetch
It uses document/DOM web, but it should be the same for react-native case - just use FormData object and append all the form fields to send.
var form = document.querySelector('form')
fetch('/users', {
method: 'post',
body: new FormData(form)
})
And:
var input = document.querySelector('input[type="file"]')
var data = new FormData()
data.append('file', input.files[0])
data.append('user', 'hubot')
fetch('/avatars', {
method: 'post',
body: data
})

Resources