Fetching data using a async function in react [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed last year.
I have been trying to create a table from an array of objects. I'm able to console the data inside the async function. But I couldn't console it outside.
My code :
useEffect(() => {
listingCampaignsModels()
}, []);
async function listingCampaignsModels() {
const apiData = await DataStore.query(Campaign);
console.log(apiData);
console.log(typeof(apiData));
return apiData;
};
When I tried to console apiData outside, it returns apiData is not defined error.
The data looks like this :
[Model, Model, Model, Model, Model, Model]
Each Model looks like :
-> 1: Model {id: 'c40d6b22-840f-467a-909c-7b2b19960ffb', campaignOwner: 'eumagnas', campaignName: "mollitlab", startDate: "2022/08/15", endDate: "2022/10/25", expectedRevenue: 25, budgetedCost: 27, actualCost: 28}
I want loop through all the Models and create a table as :
Campaign Owner
Campaign Name
Start Date
End Date
Expected Revenue
Budgeted Cost
Actual Cost
eumagnas
mollitlab
2022/08/15
2022/10/25
25
27
28

You need to use useState() hook to save the data as campaign state.
const [campaigns, setCampaigns] = useState([]);
useEffect(() => {
listingCampaignsModels()
}, []);
async function listingCampaignsModels() {
const apiData = await DataStore.query(Campaign);
console.log(apiData);
setCampaigns(apiData);
};

Related

How to change the function call based on value [duplicate]

This question already has answers here:
ES6 Import some functions as a object
(3 answers)
Closed 11 months ago.
There are 3 functions imported:
import { searchShip, searchLcl, searchFcl } from "services/logisticsService";
searchData = {
currentPort: currentPort,
destinationPort: destinationPort,
date: readyTOLoad,
type: containerType, // containerType is geting 1 value among this (ship,lcl,fcl)
}
Here I want to call one of those function based on that containerType value. For example:
If I get type value as ship then it should be
searchShip(searchData).then((response) => {
console.log(response)
})
If I get type value as lcl then it should be
searchLcl(searchData).then((response) => {
console.log(response)
})
If I get type value as fcl then it should be
searchFcl(searchData).then((response) => {
console.log(response)
})
Is there any good way to call that search function on that type condition without if else statement because inside it there is very lengthy process to handle response.
Yes, you can define an object that has a {[key]: function} structure.
const handlersByType = {
ship: searchShip,
lcl: searchLcl,
fcl: searchFcl.
};
handlersByType[type](searchData).then((response) => {
console.log(response)
})

Why is react useState not updating the values? [duplicate]

This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Best way to request unknown number of API pages in useEffect hook
(4 answers)
Closed 2 years ago.
I am using an API to fetch data, but in order to fetch all the data I am required to loop through the links
const [characterData, setCharacterData] = useState([]);
const [link, setLink] = useState("https://swapi.dev/api/people/");
useEffect(() => {
getData();
}, [])
async function getData() {
while (link) {
const fetchedData = await fetch(link);
const jsonData = await fetchedData.json();
setCharacterData([...characterData, jsonData.results]);
setLink(jsonData.next);
console.log(link)
}
}
This is how one of the jsonData from above would look like:
{
"next": "http://swapi.dev/api/people/?page=2", "previous": null, "results": [list of the wanted data] }
The last object will have "next": null, so the while loop should end at some point, but for some reason setLink() never updates the link and causes it to become an infinite loop. Link always remains as "https://swapi.dev/api/people/".
Another problem is that the page isn't displaying anything as characterData gets updated, so I am assuming that characterData isn't updating either, but I am not sure.
characterData.map((character, index) => {
return (
<div className="character-item" key={index}>
<h4>{character.name}</h4>
<p>{character.birth_year}</p>
</div>
);
})
Note: Each character is an object
Thank you!
The link is declared with const - it'll never change in a given render. So the
while (link) {
will run forever.
Unless you're using the link elsewhere, I'd remove it from state entirely and use a local variable inside getData instead. Make sure to use the callback form of setCharacterData too so that you don't lose the prior value in state.
async function getData() {
let link = 'https://swapi.dev/api/people/';
while (link) {
const fetchedData = await fetch(link);
const jsonData = await fetchedData.json();
setCharacterData(characterData => [...characterData, jsonData.results]);
link = jsonData.next;
}
}
It would also be a great idea to catch possible errors:
useEffect(() => {
getData()
.catch(handleErrors);
}, [])

Cloud Functions in Firebase Realtime Database

i've a database structure like this:
root: {
timer: 1,
data: {
id1: val,
id2: val,
},
cronology: {
id:{
id1: val,
id2: val,
},
id:{
id1: val,
id2: val,
}
}
I'm trying to make a trigger that, when the timer value is modified, it adds to cronology a child that contains the actual values of the path: '/data'.
So i created a function with the onUpdate method on the DatabaseReference '/timer'. The problem is that i don't know how to access to '/data' values in this function
export const cronologyBuilder = functions.database.ref("/timer")
.onUpdate((change, context) => {
const newdata = admin.database.ref('/data');
return admin.database.ref('/cronology').set(newdata);
});
I tried with this code but it tells me that newdata object is not good for set method.
How can i get the values of '/data' path ?
Your code is not actually querying for any data. This line of code just builds a Reference object. It does not contain any data:
const newdata = admin.database.ref('/data');
If you want to query that location, you will need to call once() on it and use the returned promise to wait for the data at that location:
return admin.database.ref('/data').once('value')
.then(snapshot => {
return admin.database.ref('/cronology').set(snapshot.val());
})
I suggest reading the documentation for the Admin SDK database API to learn how to read and write data. You will also need to understand how promises work in order to deal with them properly.

Pushing responses of axios request into array

I have been pounding my head against this problem, and need help with a solution. I have an array of IDs within a JSON, and I am iterating over that array and making a GET request of each ID. I want to then push the response of those GET requests into an array.
Here is the function I am using to push the registrations into the array. It is iterating through an array of IDs:
getRegistrations = async (event) => {
let registrations = [];
await event.registrations.forEach(registration => axios.get('/event/getRegistration', {
params: {
id: registration
}
}).then(res => {
registrations.push(res.data.properties)
}
).catch(err => console.log(err)));
return registrations;
};
Here is where I am calling that code:
render() {
let event = this.getEvent();
let registrations2 = [{
age: 19,
bio: 'test',
firstName: 'hello',
lastName: 'bye',
password: 'adadas',
telephone: "4920210213"
}];
if (this.props.listOfEvents.events.length !== 0 && !this.props.listOfEvents.gettingList && event) { //check if the array is empty and list has not been rendered yet
let columns = [];
let registrations = this.getRegistrations(event);
console.log(registrations);
let eventProperties = event.properties[0];
Object.keys(eventProperties).forEach(key => columns.push({
title: eventProperties[key].title,
dataIndex: key,
key: key
}));
console.log(registrations);
console.log(registrations2);
return (
<h1>hi</h1>
)
}
return <Loading/>
}
When I console-log 'registrations' vs 'registrations2' they should be very identical. However, in the javascript console on Google Chrome, 'registrations appears as '[]' where 'registrations2' appears as '[{...}]'.
I know that it is an issue related to promises (I am returning the registrations array before actually pushing) but I have no idea how to fix it! Some friendly help would be very much appreciated!
I recommend Promise.all, it will resolve single Promise after all promises have resolved. And technically async function is also promise so it will return promise.
here the example.
https://codesandbox.io/s/jzz1ko5l73?fontsize=14
You need to use componentDidMount()lifecycle method for proper execution and state to store the data.
constructor (props) {
super(props);
this.state = {registrations :[]}
}
componentDidMount () {
let response = this.getRegistrations()
this.setState({registrations : response});
}
Then access that state in render method. It's not good practice to call api from render mothod.
Since getRegistrations(event) returns a promise, you should perform operations on its return value inside then.
Instead of
let registrations = this.getRegistrations(event);
console.log(registrations);
Do this
this.getRegistrations(event).then(registrations => {
console.log(registrations);
// other operations on registrations
});

axios promise returns correct value in "axios.all" function, but is undefined in the "then" function

I'm following a tutorial in which data from the git API is requested and a scoring algorithm will order that data.
The battle function will take an array of two elements, i.e two github users. We retrieve the profile and score for eah user from the getUserData method
module.exports = {
battle: function(players) {
return axios.all(players.map(getUserData))
.then(response => {
response.forEach( each=>console.log(each));
return response;
})
}
}
The getProfile and getRepos functions ork correctly in retrieving objects which have data on the users profile(username, followers, etc) and their repos(repo names, etc.). So I've omitted the code for both these functions as I already know they work for certain. Additionally, the calculateScore method also works and returns output as expected.
The console.log statement shows that the object with keys "profile" and "score" is correctly made, and prints out both the profile object data and the score as expected. So far so good.
function getUserData(player) {
axios.all([
getProfile(player),
getRepos(player)
])
.then(function(data) {
var profile = data[0];
var repos = data[1];
console.log({
profile: profile,
score: calculateScore(profile, repos)
})
return {
profile: profile,
score: calculateScore(profile, repos)
}
})
}
The Problem:
The callback function in "battle" should receive an array of size 2, with each element containing the profile and score for that particular player. e.g:
[
{
profile: {profile data for player1...}
score: 10 //or whatever the score is
},
{
profile: {profile data for player2...}
score: 2 //or whatever the score is
}
]
but instead the callback function is receiving [undefined, undefined] as its input from the axios.all function
Correct me if I'm wrong, but in promises, isn't the output from the "axios.all" method supposed to be the input for the "then" method. So why am I getting undefined if the console.log statement shows that axios.all is outputting the correct data?
Your getUserData function does not return anything. Change it as below:
function getUserData(player) {
return axios.all([
// ...
]);
}
That behaviour is because you return an array of undefined values when you do response.map where you replace all the items with undefined (console.log returns undefined).
Instead, return the actual result from the asynchronous call:
module.exports = {
battle: function(players) {
return axios.all(players.map(getUserData))
.then(response => {
response.forEach(each => console.log(each));
return response;
});
}
}

Categories