Using variables in multiple functions - react native - javascript

I'm looking to fetch some data then use it to fetch some other data, the first api returns a some news articles, I'm doing a for loop to access descriptions and save it as an array, I want then to use that array to make another fetch request, the issue is that I'm only able to access arrayin the first function, my code looks like that:
makeRemoteRequest = () => {
const url = `https://url.com`;
fetch(url)
.then(res => res.json())
.then(res => {
maindata = res.articles
var array = []
for(let i in maindata){
array.push(maindata[i].description)
}
console.log(array) // Working
this.setState({
data: res.articles,
});
})
console.log(array) // Not working
console.log(this.state.data) // Not working
};
I'm able to use this.state.data in component and render it on a listview.
Second function:
fetch('url', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
'api_key': "81a354b",
'data': array
}),
})
My last attempt was to mix everything in a single function since it's all promises, didn't work
fetch(url)
.then(res => res.json())
.then(res => return res.articles.map(article => article.description) )
.then(res => fetch(otherUrl, { descriptions: res }))
.then(res => {
})

Just define the variable outside of the fetch scope first.
let array = [];
Then inside the fetch:
array.push()

What is the output of this? (could you please add the output formatted in your question?):
fetch(url)
.then(res => res.json())
.then(res => return res.articles.map(article => article.description) )
.then(res => fetch(otherUrl, { descriptions: res }))
//I assume that result needs to be parsed as json as well
.then(res => res.json())
.then(result => {
conole.log("got results:",results);
})
.catch(err =>
console.warn("something went wrong:",err);
)

Related

Update one property in MongoDB and update UI without refresh the page

I am trying to update one property Like I have a few properties, product name, price, quantity, supplier, and description. I am sending all the updated quantities with all properties to MongoDb, in that case, I am able to update the database and UI without any refresh.
const handleDelivered = (id) => {
const newQuantity = (quantity - 1);
if (newQuantity >= 0) {
const newService = {...serviceDetail, quantity: newQuantity}
setServiceDetail(newService);
const url = `https://intense-tor-77999.herokuapp.com/item/${id}`;
fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newService),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
})
}
else{
toast(`${productName} is sold out`);
}
}
But I just want to update only one property for example only quantity like
const updateQuantity = { quantity : newQuantity};
So, how can I update this one property without sending all properties from my frontend to backend?
Firstly you can declare
const [isReload, setIsReload]= useState(true);
when you get response from database after uploading new quantity, add this
.then(response => response.json())
.then(data => {
console.log('Success:', data);
setIsReload(!isReload);
});
than you put isReload as dependency of useEffect, where you load data by id
useEffect(()=>{
fetch(url)
.then(res=>res.json())
.then(data => setData(data))
},[isReload ]);
try it

Vue.js 3.0: Read and set object properties from method

I am learning and creating a Vue application. When I try setting the properties, I get an error like this, Cannot read property 'Selected.type' of undefined
This is how I try to do it:
<script>
export default {
data() {
return {
info: {},
Selected: {
type: '',
country: '',
}
};
},
methods: {
fetchData () {
fetch(`https://data.brreg.no/enhetsregisteret/api/enheter/983609155`)
.then( resp => resp.json())
.then((data) => (this.info = data))
.then(function (data) {
console.log(data.organisasjonsform.beskrivelse);
this.Selected.type=data.organisasjonsform.beskrivelse;
})
.catch(err => console.error(err))
}
},
mounted() {
this.fetchData();
},
};
</script>
Why I am getting this error? I am new to VueJS. Can someone please help me out here?
This is because this refer to the execution context of the callback-function, not the Vue component. It is caused by using the function-keyword to declare your callback instead of the newer () => {} syntax.
If you change your code to:
fetch(`https://data.brreg.no/enhetsregisteret/api/enheter/983609155`)
.then( resp => resp.json())
.then((data) => (this.info = data))
.then((data) => {
console.log(data.organisasjonsform.beskrivelse);
this.Selected.type=data.organisasjonsform.beskrivelse;
})
It should work.
An alternative syntax, is to capture the this context in a variable within the closure of your fetchData-method
fetchData () {
const self = this;
fetch(`https://data.brreg.no/enhetsregisteret/api/enheter/983609155`)
.then( resp => resp.json())
.then((data) => (this.info = data))
.then(function (data) {
console.log(data.organisasjonsform.beskrivelse);
self.Selected.type=data.organisasjonsform.beskrivelse;
})
.catch(err => console.error(err))
}
This should work, I didn't try it but it's obvious.
you have to add the 'this' before Selected.type to access it.
Edit:
My bad, I totally forgot about the function context. That's what happens when you don't run your code before posting, i guess.
fetch(`https://data.brreg.no/enhetsregisteret/api/enheter/983609155`)
.then( resp => resp.json())
.then((data) => (this.info = data))
.then((data) => {
console.log(data.organisasjonsform.beskrivelse);
this.Selected.type=data.organisasjonsform.beskrivelse;
})
.catch(err => console.error(err))
}

Express.js res.json appending to response object

I'm trying to return some json data using the res.json() function from Express, but instead of returning a new json object each time it seems that it's appending to the old json object each time. This means that I'm receiving duplicate data in the same response object.
My code looks like this:
await Promise.all(promises)
.then(responses => res.json(responses))
.catch(error => console.error(error))
Returned data example:
[
[data]
]
Second request returned data sample:
[
[data],
[data(1)]
]
My code returns a list of responses which I want, but on repeated requests to the same function the new response is appended to the data from the old response and sent back. Is this intended? Am I doing something wrong?
edit: here is the rest of my code for context. I'm new to js and async programming so let me know if something I'm doing is terribly wrong.
const fetch = require('node-fetch')
const authFunctions = require('./auth')
var bearer_token
const space_id = 11111
let id_promises = []
async function get_category_rooms(category_id)
{
return fetch(`https://url.com/api/${category_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
}).then(response => response.json())
.then(data => data.map(category => category.items))
.catch(err => console.error(err))
}
async function get_category_ids() {
return fetch(`https://url.com/api/${space_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
})
.then(response => response.json())
.then(data =>
{
categories = data[0]["categories"].filter(category => category.name !== "category i don't want")
categories.forEach(category_item =>
{
id_promises.push(new Promise((resolve, reject) =>
{
resolve(get_category_rooms(category_item.cid))
}))
})
})
}
async function get_room_bookings(room_id) {
return fetch(`https://url.com/api/${room_id}`,
{
headers:
{
'Authorization': `Bearer ${bearer_token}`
}
})
.then(response => response.json())
.then(data => data)
}
async function get_not_group_room_reservations(req,res)
{
let room_promises = []
if (!await authFunctions.auth_check(bearer_token))
{
console.log('invalid bearer token. changing bearer')
bearer_token = await authFunctions.auth()
}
await get_category_ids()
let rooms = await Promise.all(id_promises)
.then(responses =>
{
let room_ids = responses.flat(2)
room_ids.forEach(room_id =>
{
room_promises.push(new Promise((resolve, reject) =>
{
resolve(get_room_bookings(room_id))
}))
})
})
.catch(error => console.error(error))
await Promise.all(room_promises)
.then(responses => res.json(responses))
.catch(error => console.error(error))
}

Setting State with a parameter

Not sure what i'm tyring to do is possible, but
state = {
characters: [],
planets: [],
search: "",
selectedCharacter: null
};
componentDidMount() {
this.fetchSomeData(
"https://rickandmortyapi.com/api/character/",
"characters"
);
this.fetchSomeData("https://rickandmortyapi.com/api/location", "planets");
}
fetchSomeData = (url, stateToSet) => {
fetch(url)
.then(res => res.json())
.then(data => this.setState({
[stateToSet]: data.results,
next: data.info.next,
prev: data.info.prev
}))
.catch(err => alert(err));
};
I have a characters page, and a planets page both obviously 2 different endpoints from the api
https://rickandmortyapi.com/api/character/
https://rickandmortyapi.com/api/location/
the problem i'm having:
when
componentDidMount(){
}
runs it's fetching both sets of data, then storing both
next page endpoints in the next state
"https://rickandmortyapi.com/api/location/?page=2"
"https://rickandmortyapi.com/api/character/?page=2",
i need to access next when clicking a button to reload the next page of data. (one component displays characters, for that one i need the "https://rickandmortyapi.com/api/character/?page=2",
and one component displays planets for that one i need "https://rickandmortyapi.com/api/character/?page=2",
)
how can i store these 2 separately?
i was thinking of trying to match them to their respective endpoints like this:
fetchSomeData = (url, stateToSet) => {
fetch(url)
.then(res => res.json())
.then(data => this.setState({
[stateToSet]: data.results,
**[stateToSet]next: data.info.next,**
prev: data.info.prev
}))
.catch(err => alert(err));
};
but i'm not sure you can incorporate the parameter into it like that.
You need to change a small thing in fetchSomeData like below:
fetchSomeData = (url, stateToSet) => {
fetch(url)
.then(res => res.json())
.then(data => this.setState({
[stateToSet]: data.results,
[`${stateToSet}-next`]: data.info.next,
[`${stateToSet}-prev`]: data.info.prev
}))
.catch(err => alert(err));
};
used [${stateToSet}-next] Template literals. Hope it helps and demo
This will print :
{
characters: Array[20],
characters-next: "https://rickandmortyapi.com/api/character/?page=2"
characters-prev: ""
planets: Array[20],
planets-next: "https://rickandmortyapi.com/api/location?page=2"
planets-prev: ""
search: "",
selectedCharacter: ""
}
and #Croolsby's answer also nice solution.
This should do it:
fetchSomeData = (url, stateToSet) => {
fetch(url)
.then(res => res.json())
.then(data => this.setState({
[stateToSet]: {
results: data.results,
next: data.info.next,
prev: data.info.prev
}
}))
.catch(err => alert(err));
};
Then you can access it like this:
this.state.characters.next
this.state.planets.next
The general lesson here is that you can have nested objects inside this.state.

render out API data in custom format

I'm pulling data from an API which i then push it into a variable. From my script below the console reads like this
`1001,1002`
But i want it to render out in this format
(1001),(1002)
JS
this.http.post("http://localhost/app/route_list.php", { 'username': this.username}).map(res => res.json()) .subscribe(data => {
console.log(JSON.stringify(data));
var returned=[];
for(var i=0;i<data.length;i++){
returned.push(data[i].Route_ID);
console.log('this is data returned:'+returned)
Maybe this can help you:
this.http.post('http://localhost/app/route_list.php', {
username: this.username
})
.map(res => res.json())
.subscribe(data => {
const result = data
.map(item => `(${item.Route_ID})`)
.join(',');
console.log(result);
return result;
})

Categories