Multiple get requests - reactjs

I'm new with React and apis. I'm trying to make 2 get requests and assign 2 keys with their new values to "items" array. Here the "img" key coming from the second get request keeps overriding the whole object. So, it makes the first get request as if it doesn't exist. I need to just append the second key with the first key-values coming from the first fetch. Hope that does make sense.
fetch(url,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newItems = responseJson.items.map(i => {
return{
name: i.name
};
})
const newState = Object.assign({}, this.state, {
items: newItems
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});
fetch(url2,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newItems = responseJson.ebay.map(i => {
return{
img: i.picture.url[0]
};
})
const newState = Object.assign(this.state, {
items: newItems
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});

You can use this for the second request:
const newState = {
items: [...this.state.items, ...newItems]
}
this.setState(newState);

Related

How to save single object into state, from json end point axios

UPDATE:
axios
.get("https://cors-anywhere.herokuapp.com/" + "https://api.linkedin.com/v2/me", config)
.then(response => {
this.setState({profile: response.data})
})
^ saved the object in state for me :) Thanks everyone!!
I am a newbie to react. I am trying to save a single object from a JSON end point into the state of my react component. I am definitely returning the JSON data in the response. However it is not being saved into the state, can you see where I am going wrong?
// State needed for the component
constructor(props) {
super(props);
this.state = {
profile: {},
};
}
// Grabs profile data from the json url
private getProfile() {
let config = {
headers: {'Authorization':'Bearer AQVVEqNXTWV....'}
}
axios
.get("https://cors-anywhere.herokuapp.com/" + "https://api.linkedin.com/v2/me", config)
.then(response =>
response.data(profile => ({
id: `${ profile.id }`
}))
)
.then(profile => {
this.setState({
profile
});
})
// We can still use the `.catch()` method since axios is promise-based
.catch(error => this.setState({ error, isLoading: false }));
}
JOSN data returned:
{
"localizedLastName": "King",
"id": "fm0B3D6y3I",
"localizedFirstName": "Benn"
}
Your first then block looks wrong.
Try to do console.log there like this:
.then(response => {
console.log(response); // I am sure that you will get profile inside response.data or something similar
return response.data(profile => ({
id: `${ profile.id }`
}));
})
If you want to keep your first then that "prepares the data", then you should return a promise instead of data, like:
let config = {
headers: {'Authorization':'Bearer AQVVEqNXTWV....'}
}
axios
.get("https://cors-anywhere.herokuapp.com/" + "https://api.linkedin.com/v2/me", config)
.then(response => {
return new Promise((resolve, reject) => {
resolve( {
id: `${ response.data.id }`
});
});
}
)
.then(profile => {
this.setState({
profile
});
})
// We can still use the `.catch()` method since axios is promise-based
.catch(error => this.setState({ error, isLoading: false }));
Here's an example of how that would work:
I do believe that's a bit of an overkill though and you should be able to just set your state in the first then such as:
this.setState({profile: {id : response.data.id}});
Try to remove the second then, like this:
axios
.get("https://cors-anywhere.herokuapp.com/" + "https://api.linkedin.com/v2/me", config)
.then(response => {this.setState({ profile: response.data })};
})
}))

How can I dynamically rerender my api to my webpage?

So I have this api and I am making a get request in my ComponentDidMount() to dynamically render it to my page and it works. The issue I am facing is when I make a post request to add items to the list, it does not show on my webpage unless I refresh it. The backend is my data.json so I don't know if that is the problem but essentially when I make a post request, I am adding data to my data.json and I want that to rerender on my page without me refreshing it.
componentDidMount() {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
// console.log(Object.keys(item)[0])
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
// console.log(this.state.titles)
// console.log(this.state.data)
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res)
})
.catch(err => console.log(err));
}
render() {
let board = this.state.data.map((item, key) => {
return <WorkBoardContainer
key={key}
title={item[this.state.titles[key]]["title"]}
listItems={item[this.state.titles[key]]["list"].map((i) => {
return i["title"]
})}
/>
})
return (
<div className={classes.App}>
<AddButton addListItemHandler={this.addListItemHandler}/>
{board}
</div>
);
}
Try moving the fetching part as a seperate function and call it again once the post request is done.
componentDidMount() {
// fetch data when component is mounted
this.fetchData();
}
fetchData = () => {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res);
// fetch data again once post is done.
this.fetchData();
})
.catch(err => console.log(err));
}

React - Fetch multiple apis

I want to make a get request to multiple apis at the same time from 2 different urls, and then I want to just update the array "items" in the state with the new property "img", not to overwrite it. I want to keep and properties in the first request.
Here is my try.
componentDidMount(){
let url = ``;
let url2 = ``
fetch(url,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newItems = responseJson.items.map(i => {
return{
itemId: i.itemId,
name: i.name,
};
})
const newState = Object.assign({}, this.state, {
items: newItems
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});
fetch(url2,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newImg = responseJson.item.map( data=> {
return{
img: data.picture.url
};
})
const newState = Object.assign({}, this.state, {
items: newImg
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});
}
You absolutely can call two seperate APIs. The problem that you are having is that the API call that is returning last is overwriting the data that was saved from the first API call. Here is the code that will fix this.
componentDidMount(){
let api1 = `https://myapiexample1.com`;
let api2 = `https://myapiexample2.com`;
let promise1 = fetch(api1)
.then(response => response.json())
.then(json => json.items.map(item => {
return {
itemId: item.itemId
name: item.name
}
}))
let promise2 = fetch(api2)
.then(response => response.json())
.then(json => json.items.map(item => {
return {
img: item.img
}
}))
Promise.all([promise1, promise2])
.then(results => results[0].concat(results[1]))
.then(items => this.setState({itmes}))
}
An alternative approach which is not as clean, but is similar to what you are currently doing is to make sure to include the old state when adding new items to the state:
this.setState({
items: newItems.concat(this.state.items)
})
Use Promise.all():
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
Ref: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
You can use Promise.all, it will resolve when all promises are ok or reject if any fails.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

React - fetch multiple get requests

I want to make a get request to multiple apis at the same time from 2 different urls, and then I want to just update the array "items" in the state with the new property "img", not to overwrite it, I'm looking for way to just append it. I want to keep the properties from the first request. Here is my try.
componentDidMount(){
let url = ``;
let url2 = ``
fetch(url,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newItems = responseJson.items.map(i => {
return{
itemId: i.itemId,
name: i.name,
};
})
const newState = Object.assign({}, this.state, {
items: newItems
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});
fetch(url2,{
method: 'GET'
})
.then((response)=> response.json())
.then((responseJson) => {
const newImg = responseJson.item.map( data=> {
return{
img: data.picture.url
};
})
const newState = Object.assign({}, this.state, {
items: newImg
});
console.log(newState);
this.setState(newState);
})
.catch((error) => {
console.log(error)
});
}
You can use Promise.all method more info here. For example:
const p1 = fetch(url,{
method: 'GET'
})
const p2 = fetch(url2,{
method: 'GET'
})
Promise.all([p1, p2]).then(values => {
// here you have an array of reponses
console.log(values);
})
use EC6 Spread operator
this.setState({ items: { ...this.state.items, newItems } });

How to update the page after call Axios Successful ? React

so I'm doing a project that uses Axios with Json-server, but I have a problem, every time I do a Patch, I have to give F5 on the homepage for it to update, I wanted know how I could do it so that it did not happen, and automatically.
My Patch:
onSubmitDate = event => {
const newUrl = prompt("Please with new URL:");
const personCurrent = event.target.value;
axios.patch(`http://localhost:3004/employee/${personCurrent}`, {
url_git: newUrl
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
My Get:
componentDidMount() {
axios
.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
}
Someone would can help me?
I am assuming the update is on the component you are handling.
For you to create a re-render of your component, you can simply set the state. See more here
What is the format of your response? Does it include the updated data you wish to display? If that is the case, it's easy, simply do a setState in your then:
onSubmitDate = event => {
const newUrl = prompt("Please with new URL:");
const personCurrent = event.target.value;
axios.patch(`http://localhost:3004/employee/${personCurrent}`, {
url_git: newUrl
})
.then(response => {
console.log(response);
this.setState({employee: response.data})
})
.catch(error => {
console.log(error);
});
}
If the response is not providing the data you want updated in your component, your can simply do your GET of whatever data you want in the then of your PATCH and set the state on it's response. So something like this:
onSubmitDate = event => {
const newUrl = prompt("Please with new URL:");
const personCurrent = event.target.value;
axios.patch(`http://localhost:3004/employee/${personCurrent}`, {
url_git: newUrl
})
.then(response => {
console.log(response);
axios.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
})
.catch(error => {
console.log(error);
});
}

Resources