How to follow redirecting links till the actual body is retried.
That link A redirects to link B using a post request. I am not in charge of the server.
e.g https://www.efcc.gov.ng/career
const setLink = async ({ link, search, config }) => {
setResponce({ status: 'Laoding' });
try {
const resp = await fetch(link, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
// body: JSON.stringify(data) // body data type must match "Content-Type" header
});
//const json = await resp.json(); // parses JSON response into native JavaScript objects
setResponce({ status: 'Laoded rrrrrrrr', data: resp });
} catch (err) {
console.log('received error: ', err.toJSON());
setResponce({ status: 'error Net' });
}
};
Looking for some help with the Google Signin Implementation:
Why am I missing the cookies for g_csrf_token listed as part of the server side response when I am using the data-callback tag in my Google Sign in button?
Thanks for your help!!
Response passed to data-callback function handleCredentialResponse(response)
{
"clientId": "<client id>",
"credential": "<jwt token base64encoded>",
"select_by": "btn"
}
HTML and JS Code
<div id="g_id_onload"
data-client_id="<client id>"
data-context="signin"
data-ux_mode="popup"
data-nonce="randomstring"
data-auto_prompt="false"
data-callback="handleCredentialResponse">
</div>
<div class="g_id_signin" class="button_item"
data-type="standard"
data-shape="pill"
data-theme="filled_blue"
data-text="signin_with"
data-size="large"
data-logo_alignment="left">
</div>
...
function handleCredentialResponse(response) {
console.log(response); // This prints the JSON objet listed in the response above in the answer {clientId:"", credential:"", selected_by:""}
postData('/authorize', response )
.then(data => {
console.log('User authorized:', data);
})
.catch(error => {
console.error('Error:', error);
});
}
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded'
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response; // parses JSON response into native JavaScript objects
}
I am trying to convert this jQuery call to native Javascript using fetch() as mentioned in MDN (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Supplying_request_options).
$.ajax(
{
method: "GET",
url: CB_ABS_URI + "ajax/get-checkin.php",
dataType: "json",
data: { DwellingUnitID:DwellingUnitID },
})
to
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *client
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return await response.json(); // parses JSON response into native JavaScript objects
}
postData(CB_ABS_URI + "ajax/get-checkin.php", { DwellingUnitID: DwellingUnitID })
.then((data) => {
console.log(data); // JSON data parsed by `response.json()` call
});
But I can't seem to send GET data in the body. Is adding the query to ajax/get-checkin.php the only way ?
But I can't seem to send GET data in the body
fetch makes a clear distinction between the query string in the URL and the data in the request body (unlike jQuery which switches between them depending on the request method).
Is adding the query to ajax/get-checkin.php the only way ?
Yes, see the documentation:
If you want to work with URL query parameters:
var url = new URL("https://geo.example.org/api"),
params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)
I have a wrapper class for fetch promises and I wanted to console out http response statuses.
Currently the switch is inside the get() method. How can I shift this switch case into the error() method and use it as a "thenable"?
Take a look:
class CustomFetch {
get(url) {
return new Promise((resolve, reject) => {
const getOptions = {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/json',
// 'Content-Type': 'text/xml'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
// body: JSON.stringify(params) // body data type must match "Content-Type" header
};
// DO FETCH
fetch(url, getOptions)
.then(function(res) {
// RESPONSE VALIDATION
switch (res.status) {
case 200:
// code...
console.info('HTTP GET response status:', res.status, 'OK');
break;
case 201:
// code...
console.info('HTTP GET response status:', res.status, 'Created');
break;
case 404:
// code...
throw new Error('HTTP GET response status: 404 Not Found.');
break;
case 500:
// code...
throw new Error('HTTP GET response status: 500 Internal Server Error.');
break;
case 503:
// code...
throw new Error('HTTP GET response status: 503 Service Unavailable.');
break;
default:
// code...
break;
}
return res;
})
.then(res => res.json())
.then(data => resolve(data))
.catch(err => reject(err));
});
}
error(res) {
// Here, for example..
}
}
const http = new CustomFetch;
async function Run() {
// GET -> AWAIT...
const fetch1 = await http.get('https://jsonplaceholder.typicode.com/users/1')
.then(data => console.log(data))
.then(data => console.log('asycn/await: Resource Get Successful.'))
.then(data => console.log('_'))
.catch(err => console.log(err));
}
// RUN async /await fetch functions in procedural order.
Run();
If I understand what you are asking properly, you want to move the switch statement out into the error method on the class?
Because it is in the promise chain the error method would need to return a promise.
Maybe something like the following would work:
error(res) {
switch (res.status) {
case 200:
// code...
console.info('HTTP GET response status:', res.status, 'OK');
break;
case 201:
// code...
console.info('HTTP GET response status:', res.status, 'Created');
break;
case 404:
// code...
throw new Error('HTTP GET response status: 404 Not Found.');
break;
case 500:
// code...
throw new Error('HTTP GET response status: 500 Internal Server Error.');
break;
case 503:
// code...
throw new Error('HTTP GET response status: 503 Service Unavailable.');
break;
default:
// code...
break;
}
return res.json();
}
You would also need to remove this statement:
.then(res => res.json())
that follows the call.
So your get method would now look like:
(EDIT: As it has been pointed out, we must try to avoid the explicit constructor antipattern, so we would instead return the entire promise and defer the resolution and rejection to the caller)
// code above the fetch...
return fetch(url, options)
.then(this.error);
Here is the updated code to reflect the removal of explicit construction anti-pattern. This is thanks to Patrick's second comment.
This class contains GET, POST, PUT & DELETE.
The class uses fetch. Then you use async await functions to return them in order.
class CustomFetch {
// METHOD: GET
get(url) {
const getOptions = {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/json',
// 'Content-Type': 'text/xml'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
// body: JSON.stringify(params) // body data type must match "Content-Type" header
};
// DO FETCH
return fetch(url, getOptions)
.then(this.getResStatus)
}
// ================================================================================
// METHOD: POST
post(url, params) {
const postOptions = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/json',
// 'Content-Type': 'text/xml'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
body: JSON.stringify(params) // body data type must match "Content-Type" header
};
// DO FETCH
return fetch(url, postOptions)
.then(this.getResStatus)
}
// ================================================================================
// METHOD: PUT
put(url, params) {
const putOptions = {
method: 'PUT', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/json',
// 'Content-Type': 'text/xml'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
body: JSON.stringify(params) // body data type must match "Content-Type" header
};
// DO FETCH
return fetch(url, putOptions)
.then(this.getResStatus)
}
// ================================================================================
// METHOD: DELETE
delete(url) {
const deleteOptions = {
method: 'DELETE', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/json',
// 'Content-Type': 'text/xml'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
// body: JSON.stringify(params) // body data type must match "Content-Type" header
};
// DO FETCH
return fetch(url, deleteOptions)
.then(this.getResStatus)
}
// ================================================================================
// METHOD: GET RESPONSE
getResStatus(res) {
switch (res.status) {
case 200:
// code...
console.info('HTTP response status:', res.status, 'OK');
break;
case 201:
// code...
console.info('HTTP response status:', res.status, 'Created');
break;
case 404:
// code...
throw new Error('HTTP response status: 404 Not Found.');
break;
case 500:
// code...
throw new Error('HTTP response status: 500 Internal Server Error.');
break;
case 503:
// code...
throw new Error('HTTP response status: 503 Service Unavailable.');
break;
default:
// code...
break;
}
// CONVERT TO JSON...
return res.json();
}
} // end Class {}
const http = new CustomFetch;
async function Run() {
// ================================================================================
// GET -> AWAIT...
const fetch1 = await http.get('https://jsonplaceholder.typicode.com/users/1')
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Get Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// POST data
const postData = {
name: 'Mark Postman',
username: 'markpostman',
email: 'mpostman#email.com'
}
// POST -> AWAIT...
const fetch2 = await http.post('https://jsonplaceholder.typicode.com/users', postData)
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Post Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// PUT data
const putData = {
name: 'Mark Putman',
username: 'markpostman',
email: 'mpostman#email.com'
}
// PUT -> AWAIT...
const fetch3 = await http.put('https://jsonplaceholder.typicode.com/users/1', putData)
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Put Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// DELETE -> AWAIT...
const fetch4 = await http.delete('https://jsonplaceholder.typicode.com/users/1')
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Delete Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
}
// RUN async /await fetch functions in procedural order.
Run();
I'm quite new to using fetch and I dont know if I'm doing this right since it works fairly well with POST. If I use the normal fetch method, and not the function I made, the server responds with the data. But if I use this, the data becomes undefined. Any ideas on how I can fix this?
network_requests.js
export const getData = (url, data) => {
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json',
'Authorization': 'Token '+ localStorage.token
},
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json()); // parses response to JSON
};
sample usage: (doesnt work)
fetchDrivers() {
return getData('/members/drivers').then(data => {
if (!data["error"]) {
//for each entry in drivers data, append data as a dictionary in tableData
//ant tables accept values {"key": value, "column_name" : "value" } format
//I cant just pass the raw array since its a collection of objects
const tableData = [];
//append drivers with their ids as key
data["drivers"].forEach(item => tableData.push({
"key": item.id,
"name": item.name
}));
this.setState({drivers: tableData});
} else {
console.log(data["error"]);
}
});
}