I want to assign response in Fruits array ones I fetched the data from Api using fetch...But I am getting empty array when console.log.. I am getting the response from Api but not able to assign it to fruits
I am doing this way: .then(data => Fruits);
let Fruits = []
useEffect(() => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIwicm9sZSI6ImV4cGVydCJ9.6pYrAr_En0nl4N52oP1O7WRJA6PPFGCzUebauBIOEnc", },
body: JSON.stringify({"dfdfdffd"})
};
fetch('https://d.com/audis/el/lt', requestOptions)
.then(response => response.json())
.then(data => Fruits);
}, []);
Use a state
const [fruits, setFruits] = useState([]);
useEffect(() => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIwicm9sZSI6ImV4cGVydCJ9.6pYrAr_En0nl4N52oP1O7WRJA6PPFGCzUebauBIOEnc", },
body: JSON.stringify({"firebase_id":"foCzPM8MgOtg1"})
};
fetch('https://d.com/audis/el/lt', requestOptions)
.then(response => response.json())
.then(data => setFruits(data);
}, []);
You're not assigning data to anything. Try:
fetch('https://d.com/audis/el/lt', requestOptions)
.then(response => response.json())
.then(data => Fruits = data);
Also, you should use a state do store the information.
const [fruits, setFruits] = useState();
fetch('https://d.com/audis/el/lt', requestOptions)
.then(response => response.json())
.then(data => setFruits(data));
Maybe use a state?
const [fruits, setFruits] = useState([])
useEffect(() => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIwicm9sZSI6ImV4cGVydCJ9.6pYrAr_En0nl4N52oP1O7WRJA6PPFGCzUebauBIOEnc", },
body: JSON.stringify({"firebase_id":"foCzPM8MgOtg1"})
};
fetch('https://d.com/audis/el/lt', requestOptions)
.then(response => response.json())
.then(data => setFruits(data));
}, []);
console.log(fruits);
Related
I am trying to make a fetch request specifically a post request to tinyURL to shortern a url generated on my site. here is the tinyURL API
Currently, I am writing my code like this but it doesn't appear to be returning the short url.
the word tinyurl seems to be banned within links so all links
containing the word tinyurl have been replaced with "SHORT"
here is the tinyURL API https://SHORT.com/app/dev
import * as React from 'react'
interface tinyURlProps { url: string } export const useTinyURL = ({ url }: tinyURlProps) => { React.useEffect(() => {
const apiURL = 'https://api.SHORT.com/create'
const data = JSON.stringify({ url: url, domain: 'tiny.one' })
const options = {
method: 'POST',
body: data,
headers: {
Authorization:
'Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
Accept: 'application/json',
'Content-Type': 'application/json',
},
} as RequestInit
fetch(apiURL, options)
.then((response) => console.log(response))
.then((error) => console.error(error))
console.log('TinyUrl ran') }, [url])
}
The snippet below seems to work
const qs = selector => document.querySelector(selector);
let body = {
url: `https://stackoverflow.com/questions/66991259/how-to-make-a-fetch-request-to-tinyurl`,
domain: `tiny.one`
}
fetch(`https://api.tinyurl.com/create`, {
method: `POST`,
headers: {
accept: `application/json`,
authorization: `Bearer 2nLQGpsuegHP8l8J0Uq1TsVkCzP3un3T23uQ5YovVf5lvvGOucGmFOYRVj6L`,
'content-type': `application/json`,
},
body: JSON.stringify(body)
})
.then(response => {
if (response.status != 200) throw `There was a problem with the fetch operation. Status Code: ${response.status}`;
return response.json()
})
.then(data => {
qs(`#output>pre`).innerText = JSON.stringify(data, null, 3);
qs(`#link`).href = data.data.tiny_url;
qs(`#link`).innerText = data.data.tiny_url;
})
.catch(error => console.error(error));
body {
font-family: calibri;
}
<p><a id="link" /></p>
<span id="output"><pre/></span>
I have been looking at documentation on how to perform ODATA CRUD actions on a SharePoint List/Libraries using custom javascript. What I notice is that you need to import jquery to use the axios/ajax calls instead of using the ES6+ Fetch() calls. Does anyone know how to do this and if so, could you provide some examples?
Long story short, I figured it out and wanted to share the code on how I did it for those poor individuals like myself that had 20 tabs open looking for a solution.
Feel free to comment on my choices
GET
// OR YOU CAN USE THE ACTUAL address --> fetch(https://TestSite.sharepoint.us/sites/ExactSite +
fetch(_spPageContextInfo.siteAbsoluteUrl + "/api/web/lists/getbytitle('SharePoint List')/items?$filter=Id eq 1")
.then(res => res.text())
.then(str => new window.DOMParser().parseFromString(str, "application/xml"))
.then(data => {
let itemContent = data.getElementsByTagName("content");
for (i=0; i<1; i++) {
console.log(itemContent[i].childNodes[0]childNodes[1].textContent);
})
POST
You might need to get the RequestDigestValue/X-RequestDigest so I'll include it because I needed it
fetch(_spPageContextInfo.siteAbsoluteUrl + "/_api/contextInfo", {
method: 'POST',
headers: {
'Accept': "application/xml;odata=verbose",
'Content-Type': "application/xml;odata=verbose"
}
})
.then(res => res.text())
.then(str => new window.DOMParser().parseFromString(str, "application/xml"))
.then(res => {
let digValHolder = res.getElementsByTagName("d:FormDigestValue");
let digVal = digValHolder[0].textContent; //This is the value you will need to input in to the Post/Delete Function
addToList(digVal) //This is the function that will do the adding
})
const addToList = (FormDigestValue) => {
let metadata = {
column-name: "value",
__metadata: { type: "SP.Data.SharePoint_x0020_ListListItem" }
}
let postHeader = new Headers({
'X-RequestDigest': FormDigestValue,
'Accept': 'application/json; odata=verbose',
'credentials' : 'include',
'Content-Type': 'application/json; odata=verbose'
});
let postOptions = {
method: 'POST',
headers: postHeader,
credentials: 'include',
body: JSON.stringify(metadata)
}
return fetch(_spPageContextInfo.siteAbsoluteUrl + "/api/web/lists/getbytitle('SharePoint List')/items ", postHeader)
.then(res => console.log(res))
.catch(console.err)
}
DELETE
You will need to include the FormDigest again and I will include it so it will be easier than scrolling up and down on the page
fetch(_spPageContextInfo.siteAbsoluteUrl + "/_api/contextInfo", {
method: 'POST',
headers: {
'Accept': "application/xml;odata=verbose",
'Content-Type': "application/xml;odata=verbose"
}
})
.then(res => res.text())
.then(str => new window.DOMParser().parseFromString(str, "application/xml"))
.then(res => {
let digValHolder = res.getElementsByTagName("d:FormDigestValue");
let digVal = digValHolder[0].textContent; //This is the value you will need to input in to the Post/Delete Function
deleteFromList(digVal) //This is the function that will do the deleting
})
const deleteFromList = (id, FormDigestValue) => {
let deleteHeader = new Headers({
'X-RequestDigest': FormDigestValue,
'Accept': 'application/json; odata=verbose',
'credentials' : 'include',
'Content-Type': 'application/json; odata=verbose',
'IF-MATCH' : '*'
})
let deleteOptions = {
method: 'DELETE',
headers: deleteHeader
}
return fetch(_spPageContextInfo.siteAbsoluteUrl + "/api/web/lists/getbytitle('SharePoint List')/items" + id , deleteHeader )
.then(res => console.log(id + " has been deleted"))
.catch(console.err)
}
Okay, I am still new in Javascript. As per title, how to fetch a single API url but with 4 different parameters. My goal is to display 4 different categories as the result
Example (I have 4 different categories):
const category = [1,2,3,4];
I want to make each category calls for an api
Method 1
To call category 1:
const url = 'http://www.myapiurl.com/thisapi';
const parameter = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=1`
};
fetch(url, options)
.then(response => response.json())
.then(object => {})
To call category 2:
const url = 'http://www.myapiurl.com/thisapi';
const parameter = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=2`
};
fetch(url, options)
.then(response => response.json())
.then(object => {})
To call category 3:
const url = 'http://www.myapiurl.com/thisapi';
const parameter = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=3`
};
fetch(url, options)
.then(response => response.json())
.then(object => {})
To call category 4:
const url = 'http://www.myapiurl.com/thisapi';
const parameter = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=4`
};
fetch(url, options)
.then(response => response.json())
.then(object => {})
Or maybe I can simplify them a bit like this:
Method 2
const parameter1 = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=1`
};
const parameter2 = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=2`
};
const parameter3 = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=3`
};
const parameter4 = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=4`
};
Promise.all([
fetch(url,parameter1).then(value => value.json()),
fetch(url,parameter2).then(value => value.json()),
fetch(url,parameter3).then(value => value.json()),
fetch(url,parameter4).then(value => value.json()),
])
.then((value) => {
console.log(value)
//json response
})
.catch((err) => {
console.log(err);
});
But all of these are very redundant and uneccesarry repetition. What if I have 50 categories? How do I simplify all of these Fetch API calls? Please give me an enlightment. Thanks in advance
You can take it a step further. Since your method, headers and part of the body are all identical, just extract that to one function. Custom-build the parameters to the category, then call fetch.
const thatPostFunction = category => {
const method = 'POST'
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
const body = `USERID=userid&TOKEN=usertoken&CATEGORY=${category}`
return fetch(url, { method, headers, body })
}
const categories = [...category ids...]
const promises = categories.map(c => thatPostFunction(c))
Promise.all(promises)
.then((value) => {
console.log(value)
//json response
})
.catch((err) => {
console.log(err);
});
I would write a function to convert a category id to a Promise, and then write a wrapper function to convert an array of category ids to a Promise resolving to an array of fetch results:
const fetchCategory = (catId) => {
const url = 'http://www.myapiurl.com/thisapi';
const options = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=${catId}`
};
return fetch(url, options)
.then(response => response.json())
}
const fetchCategories = (categories) => Promise.all(categories.map(fetchCategory))
const categories = [1, 2, 3, 4]
fetchCategories(categories).then(categoryResults => {
// here categoryResults is an array of the fetch results for each category.
console.log(categoryResults)
})
<script>
// Faking out fetch for testing
const fetch = (url, opts) => Promise.resolve({
json: () => ({
categoryId: `${opts.body.slice(opts.body.lastIndexOf('=') + 1)}`,
more: 'here'
})
})
</script>
You can just create a function that runs all of them:
const categories = [1,2,3,4];
const postUrls = (items) => {
const promises = []
items.forEach(item => {
const url = 'http://www.myapiurl.com/thisapi';
const options = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `USERID=userid&TOKEN=usertoken&CATEGORY=${item}`
};
const prms = fetch(url, options)
.then(response => response.json())
promises.push(prms)
})
return Promise.all(promises)
}
postUrls(categories)
.then(data => console.log('Done!'))
If your API is flexible then you may be able to ask for all 4 categories at the same time. I have seen APIs do it like this:
body: `USERID=userid&TOKEN=usertoken&CATEGORY=1,2,3,4`
And I have seen them do it like this:
body: `USERID=userid&TOKEN=usertoken&CATEGORY=1&CATEGORY=2&CATEGORY=3&CATEGORY=4`
Again, your API would need to be able to enumerate through the categories and return the results in some kind of object or array.
I am trying to fetch multiple requests in an order in React. There are 3 requests,
first one gathering encoded information from backend
get token from authentication server
use api with the token.
All of them must be in order. But I am having difficulties because of async fetch function. I can't reach fetch's response outside of .then() block.
To solve it, I used await / async. But it caused another problem. My 3 requests must be in a sequencial order. When I use async, order gets broken.
Here is the code.
class App extends Component {
constructor() {
super();
this.state = { code: '', encoded: '', access_token: '', refresh_token: '' };
}
getCarDetails() {
const carId = '2F3A228F6F66AEA580'
var query = 'https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/'.concat(carId).concat('/doors')
fetch(query, {
method: 'GET',
headers: {
'Authorization': 'Bearer '.concat(this.state.access_token),
'accept': 'application/json'
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err));
}
getToken() {
var post_data = {
grant_type: 'authorization_code',
code: this.state.code,
redirect_uri: 'http://localhost'
}
fetch('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token', {
method: 'POST',
headers: new Headers({
'Authorization': 'Basic '.concat(this.state.encoded),
'Content-Type': 'application/x-www-form-urlencoded'
}),
body: queryString.stringify(post_data)
})
.then(res => res.json())
.then(data => this.setState({ access_token: data.access_token, refresh_token: data.refresh_token }))
.catch(err => console.log(err));
}
getEncodedClientIdAndClientSecret() {
if (this.state.code != null) {
fetch('http://localhost:8000/encodeClientIdAndSecret', {
method: 'POST'
})
.then(res => res.json())
.then(data => this.setState({ encoded: data.encoded }))
.catch(err => console.log(err));
}
}
componentDidMount() {
const values = queryString.parse(this.props.location.search)
this.setState({ code: values.code })
console.log(this.state)
this.getEncodedClientIdAndClientSecret();
console.log(this.state) //this state is empty
//this.getToken();
//this.getCarDetails();
}
AWAIT / ASYNC
async getEncodedClientIdAndClientSecret() {
if (this.state.code != null) {
const response = await fetch('http://localhost:8000/encodeClientIdAndSecret', {
method: 'POST'
})
const data = await response.json();
console.log(data)
}
}
If I put await / async, I am having sequence problem between 3 requests.
in order to use async await on methods like
await getEncodedClientIdAndClientSecret();
await getToken();
you need to first return a promise from those functions like:
getToken() {
var post_data = {
grant_type: 'authorization_code',
code: this.state.code,
redirect_uri: 'http://localhost'
}
return fetch('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token', {
method: 'POST',
headers: new Headers({
'Authorization': 'Basic '.concat(this.state.encoded),
'Content-Type': 'application/x-www-form-urlencoded'
}),
body: queryString.stringify(post_data)
})
.then(res => res.json())
.then(data => this.setState({ access_token: data.access_token, refresh_token: data.refresh_token }))
.catch(err => console.log(err));
}
so it can wait for the promise to finish, othewise they will run in parallel and finish in random order.
I used two classes
I call the second class as below
let s = new SearchExtend();
output = s.fetchData(search)
alert(output)
The second function:
fetchData = (search) => {
fetch('http://example.com/search.php' , {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
// Getting the search.
search: search
})
}).then((response) => response.json())
.then((responseJson) => {
return responseJson;
})
.catch((error) => {
console.error(error);
});
}
But i get in "alert" undefined
When I use this.setState instead of return, I get the following error:
warning setstate(...) can only update a mounted or mounting component
You are getting undefined because you are using promises. Initially it returns undefined and once promise is resolved you get the actually data.
A better way to handle this would be to return the promise and resolve it externally as follows:-
const fetchApi = () => {
return fetch("https://swapi.co/api/people" , {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
}).then((response) => {
return response.json();
})
.then((responseJson) => {
return responseJson;
})
.catch((error) => {
console.error(JSON.stringify(error));
});
}
fetchApi()
.then((data) => {
console.log("data", data);
})