How to convert axios to fetch? - javascript

I'm familiar with posting data with Axios, but trying to use fetch instead. How would I convert to a fetch request, I think what I'm doing is correct...
const data = new FormData();
The following axios request works:
data.append( 'Image', this.state.image, this.state.image.name );
axios.post( '/api/upload', data, {
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': 'multipart/form-data;',
}
})
.then ...
I tried to convert here;
data.append( 'Image', this.state.image, this.state.image.name );
fetch( '/api/upload', data, {
method: 'POST',
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': 'multipart/form-data;',
},
body: JSON.stringify(data)
})
.then ...
Returns 404 error, not found.
What am I failing to do here?

2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.
I'm using jsonplaceholder fake API to demonstrate:
Fetch api GET request using async/await:
const asyncGetCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
});
const data = await response.json();
// enter you logic when the fetch is successful
//example: show success modal, clear form, route to another page etc.
console.log(data);
} catch(error) {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(error)
}
}
asyncGetCall()
Fetch api POST request using async/await:
const asyncPostCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
});
const data = await response.json();
// enter you logic when the fetch is successful
//example: show success modal, clear form, route to another page etc.
console.log(data);
} catch(error) {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(error)
}
}
asyncPostCall()
GET request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
//example: show success modal, clear form, route to another page etc.
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(error)
})
POST request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
//example: show success modal, clear form, route to another page etc.
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(error)
})
GET request using Axios:
const axiosGetCall = async () => {
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
// enter you logic when the fetch is successful
// example: show success modal, clear form, route to another page etc.
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(`error: `, error)
}
}
axiosGetCall()
POST request using Axios:
const axiosPostCall = async () => {
try {
const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts', {
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
// enter you logic when the fetch is successful
// example: show success modal, clear form, route to another page etc.
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error,
// example: open a modal with error message.
console.log(`error: `, error)
}
}
axiosPostCall()

fetch only takes two arguments.
fetch('/api/upload', {
method: 'post',
body: JSON.stringify(data),
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': 'multipart/form-data;',
},
})
.then(res => res.json())
.then(json => console.log(json));

Related

cannot get XSRF-TOKEN from cookie in nextjs (Reactjs)

I create a login form using Nextjs and backend with Laravel 8, I generate an XSRF-TOKEN in Laravel then set it on cookie, I can see the token inside inspect element> application tab> cookie section, but I can't set it on my fetch request to make my login, I using redux to store my data such: products, auth, cart and etc
AuthAction.js code:
export const LOGIN_AUTH = "LOGIN_AUTH";
export const LOGOUT_AUTH = "LOGOUT_AUTH";
export const HandleLogin = (data) => {
return async (dispatch, getState) => {
const getCsrf = await fetch("http://localhost:8000/sanctum/csrf-cookie");
if (!getCsrf.ok) {
throw new Error("Faild to set csrf token");
}
console.log("getCsrf", cookie.load("XSRF-TOKEN"));
const response = await fetch("http://localhost:8000/api/app/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw Error("Login faild");
}
try {
const responseData = await response.json();
console.log("login", responseData);
dispatch({
type: LOGIN_AUTH,
user: responseData,
});
} catch (err) {
console.log("Login err", err);
throw err;
}
};
};
after console.log("getCsrf", cookie.load("XSRF-TOKEN")); nothing happened.
what do I do wrong in my code?
cookie screenshot:
request response:
Use axios instead of fetch.
Example:
axios
.get("http://localhost:8000/sanctum/csrf-cookie", {
withCredentials: true,
})
.then((response) => {
axios("http://localhost:8000/api/app/user/login", {
method: "post",
data: data,
withCredentials: true,
})
.then((response) => {
console.log("login", response.data);
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
//
});
Since your next.js and laravel apps are on different origins, you need to set fetch to explicitly send cookies.
const response = await fetch("http://localhost:8000/api/app/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
credentials: 'include'
});
You can read more about the credentials property in the MDN docs
Also, you can read the cookie in the front-end if it's http-only cookie.
Also, don't forget to set up Cross origin resource sharing in your backend app.

Sending data with fetch. How to include variable in body [duplicate]

I know that with the new Fetch API (used here with ES2017's async/await) you can make a GET request like this:
async getData() {
try {
let response = await fetch('https://example.com/api');
let responseJson = await response.json();
console.log(responseJson);
} catch(error) {
console.error(error);
}
}
But how do you make a POST request?
Long story short, Fetch also allows you to pass an object for a more personalized request:
fetch("http://example.com/api/endpoint/", {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
//make sure to serialize your JSON body
body: JSON.stringify({
name: myName,
password: myPassword
})
})
.then( (response) => {
//do something awesome that makes the world a better place
});
Check out the fetch documentation for even more goodies and gotchas:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Please note that since you're doing an async try/catch pattern, you'll just omit the then() function in my example ;)
if you want to make a simple post request without sending data as JSON.
fetch("/url-to-post",
{
method: "POST",
// whatever data you want to post with a key-value pair
body: "name=manas&age=20",
headers:
{
"Content-Type": "application/x-www-form-urlencoded"
}
}).then((response) =>
{
// do something awesome that makes the world a better place
});
The best way to POST form data to a PHP-script is the Fetch API. Here is an example:
function postData() {
const form = document.getElementById('form')
let data = new FormData()
data.append('name', form.name.value)
fetch('../php/contact.php', {
method: 'POST',
body: data,
}).then(response => {
if (!response.ok) {
throw new Error('Network response was not ok.')
}
}).catch(console.error)
}
<form id="form" action="javascript:postData()">
<input id="name" name="name" placeholder="Name" type="text" required>
<input type="submit" value="Submit">
</form>
Here is a very basic example of a PHP-script that takes the data and sends an email:
<?php
header('Content-type: text/html; charset=utf-8');
if (isset($_POST['name'])) {
$name = $_POST['name'];
}
$to = "test#example.com";
$subject = "New name submitted";
$body = "You received the following name: $name";
mail($to, $subject, $body);
2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.
I'm using jsonplaceholder fake API to demonstrate:
Fetch api GET request using async/await:
const asyncGetCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncGetCall()
Fetch api POST request using async/await:
const asyncPostCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
});
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncPostCall()
GET request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
POST request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
GET request using Axios:
const axiosGetCall = async () => {
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosGetCall()
POST request using Axios:
const axiosPostCall = async () => {
try {
const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts', {
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosPostCall()
Here is a solution for a POST request using node-fetch, with async/await.
async function post(data) {
try {
// Create request to api service
const req = await fetch('http://127.0.0.1/api', {
method: 'POST',
headers: { 'Content-Type':'application/json' },
// format the data
body: JSON.stringify({
id: data.id,
foo: data.foo,
bar: data.bar
}),
});
const res = await req.json();
// Log success message
console.log(res);
} catch(err) {
console.error(`ERROR: ${err}`);
}
}
// Call your function
post() // with your parameter of Course
Here is a complete example: After spending hours tinkering with incomplete code snippets I finally managed to post some json from javascript, pick it up using php on a server, added a data field and finally updated the original web page. Here is the HTML, the PHP and the JS. My thanks to everyone who posted the original code fragments collected here. Similar code is on-line here: https://www.nbest.co.uk/Fetch/index.php
<!DOCTYPE HTML>
<!-- Save this to index.php and view this page in your browser -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Javascript Fetch Example</title>
</head>
<body>
<h1>Javascript Fetch Example</h1>
<p>Save this to index.php and view this page in your browser.</p>
<button type="button" onclick="myButtonClick()">Press Me</button>
<p id="before">This is the JSON before the fetch.</p>
<p id="after">This is the JSON after the fetch.</p>
<script src="fetch.js"></script>
</body>
</html>
<!-- --------------------------------------------------------- -->
// Save this as fetch.js --------------------------------------------------------------------------
function success(json) {
document.getElementById('after').innerHTML = "AFTER: " + JSON.stringify(json);
console.log("AFTER: " + JSON.stringify(json));
} // ----------------------------------------------------------------------------------------------
function failure(error) {
document.getElementById('after').innerHTML = "ERROR: " + error;
console.log("ERROR: " + error);
} // ----------------------------------------------------------------------------------------------
function myButtonClick() {
var url = 'json.php';
var before = {foo: 'Hello World!'};
document.getElementById('before').innerHTML = "BEFORE: " + JSON.stringify(before);
console.log("BEFORE: " + JSON.stringify(before));
fetch(url, {
method: 'POST',
body: JSON.stringify(before),
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then(response => success(response))
.catch(error => failure(error));
} // ----------------------------------------------------------------------------------------------
<?php
// Save this to json.php ---------------------------------------
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if ($contentType === "application/json") {
$content = trim(file_get_contents("php://input"));
$decoded = json_decode($content, true);
$decoded['bar'] = "Hello World AGAIN!"; // Add some data to be returned.
$reply = json_encode($decoded);
}
header("Content-Type: application/json; charset=UTF-8");
echo $reply;
// -------------------------------------------------------------
?>
In this article, I described about the Second Parameter of fetch().
For submit JSON data
const user = { name: 'Sabesan', surname: 'Sathananthan' };
const response = await fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
For submit form
const form = document.querySelector('form');
const response = await fetch('/users', {
method: 'POST',
body: new FormData(form)
})
For file upload
const input = document.querySelector('input[type="file"]');
const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');
fetch('/avatars', {
method: 'POST',
body: data
});

How to post file data to Gitlab project using JavaScript fetch [duplicate]

I'm trying to POST a JSON object using fetch.
From what I can understand, I need to attach a stringified object to the body of the request, e.g.:
fetch("/echo/json/",
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({a: 1, b: 2})
})
.then(function(res){ console.log(res) })
.catch(function(res){ console.log(res) })
When using jsfiddle's JSON echo I'd expect to see the object I've sent ({a: 1, b: 2}) back, but this does not happen - chrome devtools doesn't even show the JSON as part of the request, which means that it's not being sent.
With ES2017 async/await support, this is how to POST a JSON payload:
(async () => {
const rawResponse = await fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 1, b: 'Textual content'})
});
const content = await rawResponse.json();
console.log(content);
})();
Can't use ES2017? See #vp_art's answer using promises
The question however is asking for an issue caused by a long since fixed chrome bug.
Original answer follows.
chrome devtools doesn't even show the JSON as part of the request
This is the real issue here, and it's a bug with chrome devtools, fixed in Chrome 46.
That code works fine - it is POSTing the JSON correctly, it just cannot be seen.
I'd expect to see the object I've sent back
that's not working because that is not the correct format for JSfiddle's echo.
The correct code is:
var payload = {
a: 1,
b: 2
};
var data = new FormData();
data.append( "json", JSON.stringify( payload ) );
fetch("/echo/json/",
{
method: "POST",
body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
For endpoints accepting JSON payloads, the original code is correct
I think your issue is jsfiddle can process form-urlencoded request only. But correct way to make json request is pass correct json as a body:
fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 7, str: 'Some string: &=&'})
}).then(res => res.json())
.then(res => console.log(res));
From search engines, I ended up on this topic for non-json posting data with fetch, so thought I would add this.
For non-json you don't have to use form data. You can simply set the Content-Type header to application/x-www-form-urlencoded and use a string:
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: 'foo=bar&blah=1'
});
An alternative way to build that body string, rather then typing it out as I did above, is to use libraries. For instance the stringify function from query-string or qs packages. So using this it would look like:
import queryString from 'query-string'; // import the queryString class
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: queryString.stringify({for:'bar', blah:1}) //use the stringify object of the queryString class
});
After spending some times, reverse engineering jsFiddle, trying to generate payload - there is an effect.
Please take eye (care) on line return response.json(); where response is not a response - it is promise.
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/echo/json/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then(function (response) {
return response.json();
})
.then(function (result) {
alert(result);
})
.catch (function (error) {
console.log('Request failed', error);
});
jsFiddle: http://jsfiddle.net/egxt6cpz/46/ && Firefox > 39 && Chrome > 42
2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.
I'm using jsonplaceholder fake API to demonstrate:
Fetch api GET request using async/await:
const asyncGetCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncGetCall()
Fetch api POST request using async/await:
const asyncPostCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
});
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncPostCall()
GET request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
POST request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
GET request using Axios:
const axiosGetCall = async () => {
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosGetCall()
POST request using Axios:
const axiosPostCall = async () => {
try {
const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts', {
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosPostCall()
I have created a thin wrapper around fetch() with many improvements if you are using a purely json REST API:
// Small library to improve on fetch() usage
const api = function(method, url, data, headers = {}){
return fetch(url, {
method: method.toUpperCase(),
body: JSON.stringify(data), // send it as stringified json
credentials: api.credentials, // to keep the session on the request
headers: Object.assign({}, api.headers, headers) // extend the headers
}).then(res => res.ok ? res.json() : Promise.reject(res));
};
// Defaults that can be globally overwritten
api.credentials = 'include';
api.headers = {
'csrf-token': window.csrf || '', // only if globally set, otherwise ignored
'Accept': 'application/json', // receive json
'Content-Type': 'application/json' // send json
};
// Convenient methods
['get', 'post', 'put', 'delete'].forEach(method => {
api[method] = api.bind(null, method);
});
To use it you have the variable api and 4 methods:
api.get('/todo').then(all => { /* ... */ });
And within an async function:
const all = await api.get('/todo');
// ...
Example with jQuery:
$('.like').on('click', async e => {
const id = 123; // Get it however it is better suited
await api.put(`/like/${id}`, { like: true });
// Whatever:
$(e.target).addClass('active dislike').removeClass('like');
});
Had the same issue - no body was sent from a client to a server.
Adding Content-Type header solved it for me:
var headers = new Headers();
headers.append('Accept', 'application/json'); // This one is enough for GET requests
headers.append('Content-Type', 'application/json'); // This one sends body
return fetch('/some/endpoint', {
method: 'POST',
mode: 'same-origin',
credentials: 'include',
redirect: 'follow',
headers: headers,
body: JSON.stringify({
name: 'John',
surname: 'Doe'
}),
}).then(resp => {
...
}).catch(err => {
...
})
This is related to Content-Type. As you might have noticed from other discussions and answers to this question some people were able to solve it by setting Content-Type: 'application/json'. Unfortunately in my case it didn't work, my POST request was still empty on the server side.
However, if you try with jQuery's $.post() and it's working, the reason is probably because of jQuery using Content-Type: 'x-www-form-urlencoded' instead of application/json.
data = Object.keys(data).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])).join('&')
fetch('/api/', {
method: 'post',
credentials: "include",
body: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
The top answer doesn't work for PHP7, because it has wrong encoding, but I could figure the right encoding out with the other answers. This code also sends authentication cookies, which you probably want when dealing with e.g. PHP forums:
julia = function(juliacode) {
fetch('julia.php', {
method: "POST",
credentials: "include", // send cookies
headers: {
'Accept': 'application/json, text/plain, */*',
//'Content-Type': 'application/json'
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty
},
body: "juliacode=" + encodeURIComponent(juliacode)
})
.then(function(response) {
return response.json(); // .text();
})
.then(function(myJson) {
console.log(myJson);
});
}
It might be useful to somebody:
I was having the issue that formdata was not being sent for my request
In my case it was a combination of following headers that were also causing the issue and the wrong Content-Type.
So I was sending these two headers with the request and it wasn't sending the formdata when I removed the headers that worked.
"X-Prototype-Version" : "1.6.1",
"X-Requested-With" : "XMLHttpRequest"
Also as other answers suggest that the Content-Type header needs to be correct.
For my request the correct Content-Type header was:
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
So bottom line if your formdata is not being attached to the Request then it could potentially be your headers. Try bringing your headers to a minimum and then try adding them one by one to see if your problem is resolved.
If your JSON payload contains arrays and nested objects, I would use URLSearchParams and jQuery's param() method.
fetch('/somewhere', {
method: 'POST',
body: new URLSearchParams($.param(payload))
})
To your server, this will look like a standard HTML <form> being POSTed.
You could do it even better with await/async.
The parameters of http request:
const _url = 'https://jsonplaceholder.typicode.com/posts';
let _body = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1,
});
const _headers = {
'Content-type': 'application/json; charset=UTF-8',
};
const _options = { method: 'POST', headers: _headers, body: _body };
With clean async/await syntax:
const response = await fetch(_url, _options);
if (response.status >= 200 && response.status <= 204) {
let data = await response.json();
console.log(data);
} else {
console.log(`something wrong, the server code: ${response.status}`);
}
With old fashion fetch().then().then():
fetch(_url, _options)
.then((res) => res.json())
.then((json) => console.log(json));
**//POST a request**
const createTodo = async (todo) => {
let options = {
method: "POST",
headers: {
"Content-Type":"application/json",
},
body: JSON.stringify(todo)
}
let p = await fetch("https://jsonplaceholder.typicode.com/posts", options);
let response = await p.json();
return response;
}
**//GET request**
const getTodo = async (id) => {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/' + id);
let r = await response.json();
return r;
}
const mainFunc = async () => {
let todo = {
title: "milan7",
body: "dai7",
userID: 101
}
let todor = await createTodo(todo);
console.log(todor);
console.log(await getTodo(5));
}
mainFunc()
I think that, we don't need parse the JSON object into a string, if the remote server accepts json into they request, just run:
const request = await fetch ('/echo/json', {
headers: {
'Content-type': 'application/json'
},
method: 'POST',
body: { a: 1, b: 2 }
});
Such as the curl request
curl -v -X POST -H 'Content-Type: application/json' -d '#data.json' '/echo/json'
In case to the remote serve not accept a json file as the body, just send a dataForm:
const data = new FormData ();
data.append ('a', 1);
data.append ('b', 2);
const request = await fetch ('/echo/form', {
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
body: data
});
Such as the curl request
curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '#data.txt' '/echo/form'
You only need to check if response is ok coz the call not returning anything.
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/echo/json/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then((response) => {if(response.ok){alert("the call works ok")}})
.catch (function (error) {
console.log('Request failed', error);
});
// extend FormData for direct use of js objects
Object.defineProperties(FormData.prototype, {
load: {
value: function (d) {
for (var v in d) {
this.append(v, typeof d[v] === 'string' ? d[v] : JSON.stringify(d[v]));
}
}
}
})
var F = new FormData;
F.load({A:1,B:2});
fetch('url_target?C=3&D=blabla', {
method: "POST",
body: F
}).then( response_handler )
you can use fill-fetch, which is an extension of fetch. Simply, you can post data as below:
import { fill } from 'fill-fetch';
const fetcher = fill();
fetcher.config.timeout = 3000;
fetcher.config.maxConcurrence = 10;
fetcher.config.baseURL = 'http://www.github.com';
const res = await fetcher.post('/', { a: 1 }, {
headers: {
'bearer': '1234'
}
});

React and NodeJS: How can i use received data from Server on Client?

I want to use received data from server on client . I use a NodeJS Server with NextJS and React.
I use this function on the server:
function addEmailToMailChimp(email, callback) {
var options = {
method: 'POST',
url: 'https://XXX.api.mailchimp.com/3.0/lists/XXX/members',
headers:
{
'Postman-Token': 'XXX',
'Cache-Control': 'no-cache',
Authorization: 'Basic XXX',
'Content-Type': 'application/json'
},
body: { email_address: email, status: 'subscribed' },
json: true
};
request(options, callback);
}
The function will be run from this point:
server.post('/', (req, res) => {
addEmailToMailChimp(req.body.email, (error, response, body) => {
// This is the callback function which is passed to `addEmailToMailChimp`
try {
var respObj = {}; //Initial response object
if (response.statusCode === 200) {
respObj = { success: `Subscribed using ${req.body.email}!`, message: JSON.parse(response.body) };
} else {
respObj = { error: `Error trying to subscribe ${req.body.email}. Please try again.`, message: JSON.parse(response.body) };
}
res.send(respObj);
} catch (err) {
var respErrorObj = { error: 'There was an error with your request', message: err.message };
res.send(respErrorObj);
}
});
})
The try method is used to verify that an email address could be successfully saved to MailChimp. An appropriate message is sent to the client.
On the Client-Side, i use this function to receive and display the data from the server:
handleSubmit() {
const email = this.state.email;
this.setState({email: ""});
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
}).then(res => {
if(res.data.success) {
//If the response from MailChimp is good...
toaster.success('Subscribed!', res.data.success);
this.setState({ email: '' });
} else {
//Handle the bad MailChimp response...
toaster.warning('Unable to subscribe!', res.data.error);
}
}).catch(error => {
//This catch block returns an error if Node API returns an error
toaster.danger('Error. Please try again later.', error.message);
});
}
The problem: The email address is saved successfully at MailChimp, but the message is always displayed: 'Error. Please try again later.'from the .catch area. When i log the error from the catch area i get this:
TypeError: Cannot read property 'success' of undefined
Where is my mistake? I have little experience in Node.js environments. I would be very grateful if you could show me concrete solutions. Thank you for your replies.
With fetch theres no data property on the response. You have to call res.json() and return that promise. From there the response body will be read and deserialized.
handleSubmit() {
const email = this.state.email;
this.setState({email: ""});
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
})
.then(res => {
console.log(res); //to make sure the expected object is returned
if(res.data.success) {
//If the response from MailChimp is good...
toaster.success('Subscribed!', res.data.success);
this.setState({ email: '' });
} else {
//Handle the bad MailChimp response...
toaster.warning('Unable to subscribe!', res.data.error);
}
}).catch(error => {
//This catch block returns an error if Node API returns an error
toaster.danger('Error. Please try again later.', error.message);
});
}
Two things you need to change:
Call and wait for res.json() to get the response body as json object.
The result of 1. is your 'data' object that you can use directly
handleSubmit() {
//...
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
})
.then(res => res.json())
.then(data => {
if(data.success) {
//...
toaster.success('Subscribed!', data.success);
} else {
toaster.warning('Unable to subscribe!', data.error);
}
}).catch(error => {
//...
});
}

React JS how to pass values between pages using session storage

I have a react JS login page that accepts the user name and password. Upon entering the user name and and password, the credentials are processed against a json (API) file, which generates a token for the client. My goal is to pass the token to a landing page after the client has logged in and populate a dropdown list with the clients respective data. The problem I am facing is getting the clients token to pass from my login page to the landing page.
In my login page, I am using Fetch to retrieve the token from the API and then store the token using session-storage. The code snippet for getting the token:
componentDidMount() {
this.fetchData();
}
//request the token
fetchData() {
return fetch('http://myapiaut:1111/api/auth', {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({
username: 'myAdminusername',
password: 'myAdminPassword',
Authorization: 'myAdminPassword',
})
}) /*end fetch */
.then(results => results.json())
.then(data => {
this.setState({ data: data })
sessionStorage.setItem("token", data)
})
}
//authenticate request
requestUserInfo() {
var token = sessionStorage.getItem("token");
return fetch('http://myapiaut:1111/api/auth', {
method: 'GET',
headers: new Headers({
Authorization: 'Bearer' + sessionStorage.token
}),
})
.then((response) => response.json());
}
Landing page
componentDidMount() {
fetch('http://myapiclients:22222/api/clients', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization': 'Bearer ' + sessionStorage.token
},
})
.then(results => results.json())
.then(data => this.setState({ data: data }))
}
...going back to the login page, I confirmed that I'm getting the token via fetchData function, but the problem I am encountering is properly storing the token so that it may be passed to the landing page.
FYI- I've already built the landing page and it functions properly when I manually copy the generated token into the Authorization section of the Fetch.
...Could, I please get some help as to what I'm doing wrong?
The problem is here:
.then(data => this.setState({ data: data }))
.then(data => sessionStorage.setItem('token', data))
setState doesn't resolve a Promise so it does not have then()
Change it to something like:
.then(data => {
this.setState({ data: data })
sessionStorage.setItem('token', data)
})
In landing page:
componentDidMount() {
fetch('http://myapiclients/api/clients', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization': 'Bearer ${token}' // token is not defined!
},
})
.then(results => results.json())
.then(data => this.setState({ data: data }))
}
token is not defined, so it will be 'Bearer undefined', either define it before fetch(...) with sessionStorage.getItem("token") or in fetch headers do something like:
'Authorization': 'Bearer ' + sessionStorage.token

Categories