Can I pass dynamic values to ES6's Template Literals? - javascript

getSelectedCityId() {
let citiName
citiId;
axiosInstance
.get("/api/cities")
.then(response => {
if (response.status === 200 && response.data) {
citiName = this.state.city;
citiId = this.state.city.city_id;
}
})
.catch(error => {});
let url = `/api/${citiName}/${citiId}/schools/`;
axiosInstance
.get(url)
.then(response => {
})
.catch(error => {
console.log(error);
});
}
When I hit that API call,the url shows :
localhost:9000/api/undefined/undefined/schools/
I'm trying to pass the data I will get from the 1st API call as a parameter to the second API.My point is,why the template literal is throwing undefined ? Are we not allowed to pass dynamic data through template literals ?

getSelectedCityId() {
let citiName
citiId;
axiosInstance
.get("/api/cities")
.then(response => {
if (response.status === 200 && response.data) {
citiName = this.state.city;
citiId = this.state.city.city_id;
this.getSelectedCityIdStepTwo(`/api/${citiName}/${citiId}/schools/`);
}
})
.catch(error => {});
}
getSelectedCityIdStepTwo(url) {
axiosInstance
.get(url)
.then(response => {
})
.catch(error => {
console.log(error);
});
}
This will ensure the second AXIOS call isn't made until the first one is completed and there is a valid URL to pass.

Since getting /api/cities data is async operation, you need to wait for the result. Just for proof of concept:
getSelectedCityId()
{
let citiName
citiId;
axiosInstance
.get("/api/cities")
.then(response => {
if (response.status === 200 && response.data) {
citiName = this.state.city;
citiId = this.state.city.city_id;
return `/api/${citiName}/${citiId}/schools/`;
}
return null;
})
.then(url => {
if(url) { // the data from previous then
axiosInstance.get(url) //.then().catch()
}
});
}

Related

How can i get json in axios with react native?

I'm trying to get json in axios
but if i use my code this error and warning occured
How can i get response.json ??
response.json is not a function
this is my code
// url="https://yts.lt/api/v2/list_movies.json?sort_by=like_count&order_by=desc&limit=5"
url is props
useEffect(() => {
axios
.get(url)
.then((response) => response.json())
.then((json) => {
console.log('json', json);
setData(json.data.movies);
})
.catch((error) => {
console.log(error);
});
}, []);
The response object from axios stores its data in response.data.
useEffect(() => {
axios
.get(url)
.then((response) => {
const json = response.data;
console.log('json', json);
setData(json.data.movies);
})
.catch((error) => {
console.log(error);
});
}, []);
Use this:
useEffect(() => {
axios
.get(url)
.then((response) => response.data)
.then((json) => {
console.log('json', json);
setData(json.data.movies);
})
.catch((error) => {
console.log(error);
});
}, []);

function not return value from request

I made a function to get request. It look like this
export const toggleCompleted = (id) => {
axiosMethod.get('api/taks/toggle/' + id)
.then(res => {
console.log(res.data)
return res.data;
}).catch(error => {
return error;
})
return 'Test';
}
I want to get this request and if PHP return true, run dispatch. So I made this code
const markAsCompleted = (id) => {
console.log(toggleCompleted(id));
if (toggleCompleted(id) == 1){
toggleMarkAsCompleted(id);
}
}
toggleCompleted is a my request which is show before
toggleMarkAsCompletedis my dispatch.
If toggleCompleted return 1 I want to run my dispatch. It's simple? Interested is that this code
console.log(toggleCompleted(id));
return Test while my request 1 or 0 (from .then()). Why?
Add return in the toggleCompleted and use async/await to get return data
export const toggleCompleted = (id) => {
return axiosMethod
.get("api/taks/toggle/" + id)
.then((res) => {
console.log(res.data);
return res.data;
})
.catch((error) => {
return error;
});
};
const markAsCompleted = async (id) => {
const res = await toggleCompleted(id);
if (res == 1) {
toggleMarkAsCompleted(id);
}
};

Refactoring how react/node handles response

I'm using a react frontend and fetching data from my node server. I feel like my code looks a bit redundant, is there a better way to refactor all this?
App.js
searchStock = async (value) => {
let priceURL = `/stock/${ value }/price`
// fetch price data
fetch(priceURL)
.then(res => {
if (res.ok) {
res.json()
.then( (result) => {
this.setState({
price: result
})
})
}
else {
console.log("Something went wrong...")
}
})
}
server.js
app.get('/stock/:symbol/price', (req, res) => {
const token = 'abcde123'
const symbol = req.params.symbol
const apiURL = `https://sandbox.iexapis.com/stable/stock/${symbol}/price?token=T${token}`
fetch(apiURL)
.then(response => {
console.log(response.status)
if (response.ok) {
response.json().then((data) => {
res.json(data)
});
}
else {
res.sendStatus(response.status)
}
})
.catch(error => {
console.log(error);
});
})
As these two code segments live in different apps (frontend and backend) I don't think there's a pretty way of DRYing this.
Introduce library file with fetching logic
src/helper.js
exports.fetchHelper = (url) => fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
res.sendStatus(response.status)
}
})
.catch(console.error);
and use respectively
app.js
import { fetchHelper } from 'src/helper'; // or whatever else your bundler setup requires
searchStock = async (value) => {
const priceURL = `/stock/${ value }/price`;
await fetchHelper(priceURL).then((result) => {
this.setState({
price: result
})
})
}
server.js
const fetchHelper = require('src/helper').fetchHelper;
app.get('/stock/:symbol/price', (req, res) => {
const token = 'abcde123'
const symbol = req.params.symbol
const apiURL = `https://sandbox.iexapis.com/stable/stock/${symbol}/price?token=T${token}`
fetchHelper(apiURL).then((response) => {
res.json(data);
})
Or something similar...

its passing as combined values 4,5,6

I am new to promise.
I need to make two different api calls.
from the result of first api call I am getting id in the variable firstAPIid,
https://reqres.in/api/users?page=2
I need to pass this id firstAPIid to the second api call.
but the problem is its passing as combined values 4,5,6 https://jsonplaceholder.typicode.com/comments?postId=4,5,6
from the second api call I need to retrieve email and display it in the browser.
do I need to use promise or async or with redux itself can I achieve it.
I researched and referred the below links but still no luck
https://medium.com/#bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
can you tell me how to fix it.
providing my code snippet and sandbox below
https://codesandbox.io/s/redux-async-actions-xjdo7
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
dispatchFunc({
type: "RECEIVED_DATA",
payload: response.data.data
});
let firstAPIid = response.data.data.map(obj => {
return obj.id;
});
console.log("firstAPIid---->", firstAPIid);
return new Promise((resolve, reject) => {
//var url = `https://jsonplaceholder.typicode.com/comments?postId=3`;
var url =
`https://jsonplaceholder.typicode.com/comments?postId=` +
firstAPIid;
//response.data.data[0].id;
console.log("second url---->", url);
axios
.get(url)
.then(response => {
var lFilterData = "";
//memberGroupingHelper.filterData(response.data, additionalParams);
resolve(lFilterData);
})
.catch(error => {
if (error.response) {
console.log(
`############## service error from helpeeeeeer reject`
);
}
reject("");
});
});
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
I found your issue. It is happening because you are not processing the result of the promise. To do that just add the .then() and .catch() functions:
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
dispatchFunc({
type: "RECEIVED_DATA",
payload: response.data.data
});
let firstAPIid = response.data.data.map(obj => {
return obj.id;
});
console.log("firstAPIid---->", firstAPIid);
return new Promise((resolve, reject) => {
//var url = `https://jsonplaceholder.typicode.com/comments?postId=3`;
var url =
`https://jsonplaceholder.typicode.com/comments?postId=` +
firstAPIid;
//response.data.data[0].id;
console.log("second url---->", url);
axios
.get(url)
.then(response => {
var lFilterData = "";
//memberGroupingHelper.filterData(response.data, additionalParams);
resolve(lFilterData);
})
.catch(error => {
if (error.response) {
console.log(
`############## service error from helpeeeeeer reject`
);
}
reject("");
});
}).then((previousResponse) => {
//Here you resolved the promise with the resolve value above
console.log(previousResponse)
}).catch((error) => {
//Here you resolved the promise with the reject value above
console.log(error);
});
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
I am not seeing any use of the Promise because what you want to achieve can be done just with axios.
EDIT:
Just with axios you can get it. Modify as below:
<FetchButton
onFetchClick={() => {
store.dispatch(dispatchFunc => {
dispatchFunc({ type: "FETCH_DATA_START" });
axios
.get("https://reqres.in/api/users?page=2")
// axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log("response.data.data---->", response.data.data);
console.log(
"response.data.data[0].id---->",
response.data.data[0].id
);
//First of all we'll create the number of requestes base on the previous Response
const promises = response.data.data.reduce((previousValue, { id }) => {
previousValue.push(axios.get(`https://jsonplaceholder.typicode.com/comments?postId=${id}`));
return previousValue;
},[]);
//We use the built in function to fetch the data
axios.all(promises)
.then((responses) => {
//Here you have all responses processed
const emailsMapped = responses.reduce((previousValue, { data }) => {
const emails = data.map(({ email }) => email)
previousValue.push(...emails);
return previousValue;
}, [])
//You send the emails you want
dispatchFunc({
type: "RECEIVED_DATA",
payload: emailsMapped
});
console.log(emailsMapped);
})
})
.catch(err => {
dispatchFunc({ type: "FETCH_DATA_ERROR", payload: err });
});
});
}}
/>
Also modifies this line in DataList without the first_name
listItems.push(<div key={fetchedDataId++}>{elem}</div>);

having trouble chaining multiple axios request

Ok, so what I am trying to do is do an axios.get() request pull specific data an id specifically, then use that id that I got to put it as a string literal so I can do my second request. I keep getting Info is not defined.
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
info = response.data.id;
})
.then(
axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
)
.then(response => {
summoner = response.data;
return summoner;
});
let getSummonerId = (req, res) => {
res.status(200).send(summoner);
};
module.exports = {
getSummonerId
};
Fix your chaining:
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
return response.data.id;
})
.then(info => {
return axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
})
.then(response => {
summoner = response.data;
return summoner;
});
Personally, I recommend async for tasks such as this. Makes handling things a lot easier with promises:
let fetchSummoner = async() => {
const res = await axios.get(`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`);
const info = res.data.id;
const res2 = await axios.get(`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`);
const summoner = res2.data;
return summoner;
}
In the current code you haven't added a return statement in the 2nd axios request. Failing to this will not fetch and return the 2nd url.
Please try the below code.
axios
.get(
`https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/bloodstrive?api_key=${api}`
)
.then(response => {
return response.data.id;
})
.then(info => {
return axios.get(
`https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${info}?api_key=${api}`
)
})
.then(response => {
summoner = response.data;
return summoner;
});

Categories