API call (fetch) with user token through Javascript (React.js) - javascript

how are you guys doing??
I'm trying to fetch data (in React with JS) from a website X (that has cors-enabled) but need first to get a user token from a website Y and I don't know how to figure that out. Somehow I think that I have to get the user token from Y, save it in a variable and add it as a header on the other call but I'm kinda lost with the GET/POST methods.
By now what I have is this but somehow doesn't work, I think I'm not sending properly the head or making the actual calls correctly:
getToken(){
const url = 'websiteOfTheToken';
const response = await fetch(url);
const data = await response.json();
this.setState({
userToken: data.image
});
}
And:
getData(){
const response = await fetch('websiteOfTheData', {
method: 'POST',
mode: 'no-cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'accept': 'application/json',
'Content-Type': 'application/json'
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify({
title: '' // I don't know what is this doing
})
}).catch( error => {
console.log('Error fetching and parsing data ', error)
});
this.setState({
data: response.json()
});
}
Thank you in advance!!

A few things I want to say / ask about:
Typically you get the token after a successfull login, so a standard request for a token would be a post request with the user data.
An await in javascript works only inside async functions, read about it.
The most common practice for handling api responses (Promise) is to use then-catch blocks, read about it.
A typical JWT header you need to attach to your requests looks like this: "Authorization": "Bearer theactualtoken1234".
The body of the fetch post request is the actual data you're sending to the server. So its contents are totally arbitrary - I also don't have an idea what this "title": "" is doing...

Related

How to handle successful fetch POST if we don't need to do anything else?

If I have a simple fetch request like this;
var body = JSON.stringify({
"param1": Date.now(),
"param2": "Some parameter"
})
fetch(url, {
method: "POST",
headers: {
"Authorization": `Basic ${credentials}`,
"Content-Type": "application/json"
},
body: body
})
.then(response => response.text())
.catch(error => console.log('error', error));
and the response from the API will either be a 200 (Success) or not. Unless there is an error, I don't need to do anything with the response if it is successful so what can I do in the .then block of the fetch response? I tried just putting in;
.then(response)
but I get an error saying response not defined.
Even if I were to check and confirm that the response status is a 200 (i.e.: response.status === "200"), what should I put after that? I don't want to console.log it or anything. I really don't want to anything if successful. What should I do?
Maybe I'm not explaining myself well but I do run into this where I'm just posting to an API and if it's successful, I don't need to do anything else.

Get all Products with an API request in BigCommerce

I want to get a list of all the products from my BigCommerce store using an API call. This is the code I have used:
fetch("https://api.bigcommerce.com/stores/##########/v3/catalog/products", {
method: "GET",
mode: "no-cors",
"X-Auth-Token": "###############################",
"Content-Type": "application/json",
Accept: "application/json",
})
.then((res) => res.json())
.then((json) => console.log(json));
I have used the correct store hash and access token but I get this error:
I understand this is a very basic question but I would like some help as I am stuck.
Using the rest client extension and the same credentials, I am able to get the list of products:
I believe you're missing the headers object as well as missing quotes around Accept. Also, if you're running this on the client side, this will not work, as you 'd need make a server side API request to get all products. To do so, you will need to make the API request to some middleware application.
In addition to making the request on the server side, try modifying it a bit to look like this:
fetch(`url`,{
method: 'GET',
headers: {
'X-Auth-Token': '<token>',
'Content-Type': 'application/json',
'Accept': `application/json`
}
})
.then((res) => res.json())
.then((json) => console.log(json));

Fetch API: PUT request for JSON returning 404 while GET is working properly

I have 1 json file: { "clicks": 0 }
I'm trying to retrieve the data from it and then update it. The GET works, but the PUT does not.
I use Typescript which should not be a problem:
const getClickCounterJsonData = () => fetch(
'click-counter.json',
{
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
}
)
.then(response => response.json())
.then(myJson => myJson);
// this call is actually added to onClick, but you get the idea
getClickCounterJsonData().then(data => console.log(data['clicks'])); //this works, returns the actual value of the clicks property
Now the not working updating function:
const updateClickCounterJsonData = (newData: any) => fetch(
'click-counter.json',
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(newData)
}
)
.then(response => response.json())
.then(myJson => myJson);
// again in a onClick function
updateClickCounterJsonData({ clicks: 5 }).catch(error => console.log(error)); // this returns SyntaxError: Unexpected token < in JSON at position 0
// and also the request in the Network tab says 404 Not Found with a preview text: Cannot PUT click-counter.json
Am I not allowed to do PUT requests to a json resource? I'm not super familiar with the topic, but found a lot of resources that this should be possible. The GET works as expected and the PUT seems to be well configurated but I don't know why it doesn't work.
Am I missing something?
Servers may route requests based on the HTTP request type - for example express/node.js server provides explicit methods to process PUT, POST and GET requests using app.put, app.post and app.get respectively. The logic of this comes under the umbrella of "request routing". If no route is encountered that matches a request pattern, typically the router is coded to fall through to server code that responds with a 404 error.
Hence you can't just change a GET request that works into a PUT request and expect the server to adapt - it would need code changes to do so.

How do I fetch cookie data with React?

I have a MERN + Passport.js application that is using fetch to make a call to my express API in order to retrieve data stored in a cookie. I have my React frontend routed to localhost:3000, and my backend routed to localhost:3001. My cookies are not being saved, and thus my session is not persisting within my browser. It is not an issue with the express-sessions or passport middleware, as when I use POSTMAN to execute the necessary calls to my API, the cookie is stored and the session persists.
It is only when I attempt to pass this information through/to my front end that things go wrong. I have been stumped for a while and can't seem to find an answer anywhere.
This is the line that I am using to save the cookie:
handleLogin(event) {
event.preventDefault();
fetch("http://localhost:3001/users/login", {
// credentials: 'include',
credentials: 'same-origin',
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
})
// .then( (response) => response.json())
.then( (response )=> {
if(response.message){
alert(response.message);
}
})
Which correctly calls my API, which logs the current session, user data, and cookie.
Upon refreshing and making another request, I lose the cookie (it was never properly stored in the first place I think), and all session data.
This is the get request that I make whenever I navigate to a new page:
componentDidMount(){
var current_user = "";
fetch("http://localhost:3001/users/", {
// credentials: 'include',
credentials: 'same-origin',
method: "get",
headers: {
'Accept':'application/json',
'Content-Type': 'application/json'
}
})
// .then( (response)=> response.json())
.then( (response)=> {
if(response.user){
current_user = response.user;
this.setState({
user: current_user
}), ()=> console.log(response);
}
})
}
In response, I get an undefined user and no other response, and the cookie is never stored in my browser. But again, if I do this in POSTMAN, strictly doing the POST request followed by that GET request, the proper user data is returned and the cookie is shown in POSTMAN as well.
Any idea as to why fetch is not passing the cookie information back to my front end? I have tried both credentials: 'include' and credentials: same-origin.
Thank you!
It seems like the problem, or at least part of it, is your use of same-origin. From Mozilla docs (italics my own):
omit: Never send cookies.
same-origin: Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script. This is the default value.
include: Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.
The definition of "same origin" does not include different ports.
If you change same-origin to include, fetch should start managing your cookies correctly.
If not - do you know for sure that the cookie is "never stored in the browser"? With Chrome, you can check chrome://settings/siteData.

How to Use Javascript's Fetch to get POST Request Data?

I am trying to make a POST request using Javascript's fetch method as described here.
I get a ReadableStream instead of a usual json response, such as what I would get with jQuery, Angular, whatever.
My code is here: https://jsbin.com/vuwilaviva/edit?css,js,output
var request = new Request('https://httpbin.org/post', {
method: 'POST',
mode: 'cors',
data: 'The sky is green',
redirect: 'follow',
headers: new Headers({
'Content-Type': 'text/plain'
})
});
// Now use it!
fetch(request).then(function(resp) {
console.log('Logging response...')
console.log(resp);
});
The test API endpoint works fine with postman, curl, etc, so I am sure I am using fetch wrong, and it's not an issue with the API (it just returns whatever string is passed to it as data):
Edit: The current answer doesn't actually get the data returned by the post request - it's nowhere to be found in the logged json:
response.json should be used for this
fetch(request)
.then(response => response.json())
.then(json => console.log(json));

Categories