The response for an api call is like so:
//Calling the api
useEffect(() => {
runFunction(params, someMoreParams);
});
async function setDeliveryOptions(cartItems, checkoutState) {
const response = await authFetch({
url: `apiURL`,
method: 'POST',
body: JSON.stringify(orderBody),
});
const jsonResponse = await response.json();
console.log(jsonResponse);
const deliveries = jsonResponse.deliveries.map(
(items) => items.scheduleOptions,
);
const jsonResponse = await response.json();
console.log(jsonResponse);
//RESPONSE:
deliveries: Array(1).
0: items: (2) [{…}, {…}]
options: 0: //THIS IS THE DATA I WANT
end: "2022-09-01T15:15:00Z"
price:55
price_ex_vat: 44
start: "2022-09-01T15:15:00Z"
type: "POSTAL"
[[Prototype]]: Object
supplier: "supplier"
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)
const data = jsonResponse.options.map(
(items) => items.options,
);
// trying to save data:
const type = data.map((items) => items);
const start = data[0].map((items) => items.start);
const end = data[0].map((items) => items.end);
const price = data[0].map((items) => items.price);
console.log('deliveries', data);
console.log('type', type);
console.log('start', start);
console.log('end', end);
console.log('price', price);
}
how do i get the data and save it to a variable. this is run on react, and is called when website is rendered. This code saves the data to the variables but i get a react error stating that values are undefined. maybe it is a react thing?
thanks for any help
Related
I'm using firestore to store posts each post could have simple properties such as {title: 'hi', comment: true} I'm able to easily fetch the user's specific posts since my collection structure looks like this: posts/user.id/post/post.name so an example will be posts/1234sofa/post/cool day
with this way of structuring, I'm able to easily fetch data for the user, but I'm having trouble with two things how do I fetch and display all posts for my main feed, and what's the most effective way of doing this? here is my current function for fetching user-specific data:
const submitpost = async () => {
try {
const collectionRef=collection(db,`posts`,user.uid.toString(),'post')
await addDoc(collectionRef, {
post: post,
timestamp: serverTimestamp(),
canComment: switchValue,
user: user.uid,
avatar: user.photoURL,
username: user.displayName,
});
toast({ title: "posted", status: "success", duration: 2000 });
} catch (error) {
console.log(error);
}
};
this specific function creates a structure like this in firebase posts are just takes and take is singular post respectively I just changed the name so its easier to understand:
now here is how im fetching the data for my spefic user:
const [user] = useAuthState(auth);
const [takes, settakes] = useState([]);
const getData = async () => {
// if user is present run function
if (user) {
// const docRef = doc(db, "users", user.uid);
// const collectionRef = collection(docRef, "takes");
// const querySnapshot = await getDocs(collectionRef);
try {
const docRef = doc(db, "posts", user.uid);
const collectionRef = collection(db,'posts',user.uid,'takes');
const querySnapshot = await getDocs(collectionRef);
const data = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data(),
}));
settakes(data);
} catch (error) {
console.log(error);
}
//
}
};
here is the function that doesn't work when fetching all data for main feed:
const [user]=useAuthState(auth)
const [allfeed, setallfeed] = useState([])
const getData = async () => {
if(user){
const collectionRef = collection(db, "posts");
const querySnapshot = await getDocs(collectionRef);
const data = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data(),
}));
// get data from firebase
setallfeed(data)
}
}
useEffect(() => {
getData()
console.log('ran');
console.log(allfeed);
// rerun when user is present
}, [user]);
when I console log the allfeed it returns an empty array so my main problem is how to do I get all the data from the posts collection meaning posts/userid/post/post.title I need to get these for every user. and secondly is there a more efficient way to structure my data?
I would suggest using the onSnapshot() method if you want realtime updates from a collection or a specific document.
setState() does not make changes directly to the state object. It just creates queues for React core to update the state object of a React component. If you add the state to the useEffect, it compares the two objects, and since they have a different reference, it once again fetches the items and sets the new items object to the state. The state updates then triggers a re-render in the component. And on, and on, and on...
If you just want to log your data into your console then you must use a temporary variable rather than using setState:
const getData = async () => {
if(user){
// Using `getDocs`
const collectionRef = collection(db, "posts");
const querySnapshot = await getDocs(collectionRef);
const data = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data(),
}));
console.log(data)
// ============================================= //
// Using `onSnapshot()`
const q = query(collection(db, "posts"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const data = querySnapshot.docs.map(d => ({
id: d.id,
...d.data()
}))
console.log(data)
});
}
}
useEffect(() => {
getData();
}, []);
You could also use multiple useEffect() to get the updated state of the object:
const getData = async () => {
if(user){
// Using `getDocs`
const collectionRef = collection(db, "posts");
const querySnapshot = await getDocs(collectionRef);
const data = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data(),
}));
setallfeed(data)
// ============================================= //
// Using `onSnapshot()`
const q = query(collection(db, "posts"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const data = querySnapshot.docs.map(d => ({
id: d.id,
...d.data()
}))
setallfeed(data)
});
}
}
useEffect(() => {
getData();
}, [])
useEffect(() => {
console.log(allfeed);
}, [allfeed]);
If you want to render it to the component then you should call the state in the component and map the data into it. Take a look at the sample code below:
const getData = async () => {
if(user){
// Using `getDocs`
const collectionRef = collection(db, "posts");
const querySnapshot = await getDocs(collectionRef);
const data = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data(),
}));
setallfeed(data)
// ============================================= //
// Using `onSnapshot()`
const q = query(collection(db, "posts"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const data = querySnapshot.docs.map(d => ({
id: d.id,
...d.data()
}))
setallfeed(data)
});
}
}
useEffect(() => {
getData()
}, []);
return (
<div>
<p>SomeData: <p/>
{items.map((item) => (
<p key={item.id}>{item.fieldname}</p>
))}
</div>
);
For more information you may checkout these documentations:
Get data with Cloud Firestore
Get realtime updates with Cloud Firestore
Here is my code :
let namesList = ref([]);
const GetFormData = (payload) => {
return new Promise((resolve, reject) => {
api
.get("api.php", { params: { search: payload } })
.then((response) => {
data.value = response.data;
// console.log(data.value);
// convert array objects to array strings
namesList = data.value.map(function (list) {
return list["first_name"];
});
// console.log(namesList);
})
.catch((error) => {
reject(error);
});
});
};
If I console the namelist inside the function it returns the value :
(9) ['Michael Angelodfsed', 'Mardin', 'Joemar', 'Chirs', 'chan', 'loys', 'Lorena', 'kayabusa', 'kayabusa']
0: "Michael Angelodfsed"
1: "Mardin"
2: "Joemar"
3: "Chirs"
4: "chan"
5: "loys"
6: "Lorena"
7: "kayabusa"
8: "kayabusa"
length: 9
[[Prototype]]: Array(0)
but if I console the variable outside the function it gives me this console.log(nameList);
RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: Array(0), _value: Proxy}
dep: Set(1) {ReactiveEffect}
__v_isRef: true
__v_isShallow: false
_rawValue: []
_value: Proxy
[[Handler]]: Object
[[Target]]: Array(0)
[[IsRevoked]]: false
value: (...)
[[Prototype]]: Object
please help me guys. really struggling here. really appreciate your help.
Follow this:
consf nameList = ref([])
console.log(nameList.value) // get value
nameList.value = ["Shin"] // set value
As #Deepak stated, you are trying to access the variable before the function (the api call) ends.
Your namesList is a ref object, so when you log it before it ends, it logs the object.
As your function is calling an api and use a Promise, you can change your function code to this:
const GetFormData = (payload) => {
return new Promise((resolve, reject) => {
api
.get("api.php", { params: { search: payload } })
.then((response) => {
data.value = response.data;
// console.log(data.value);
// convert array objects to array strings
namesList = data.value.map(function (list) {
return list["first_name"];
});
// console.log(namesList);
resolve(namesList);
})
.catch((error) => {
reject(error);
});
});
};
GetFormData(payload).then(data => console.log(data))
Given url Data==> need to get only Karnataka state details
[{"id":1,"title":"TELANGANA","image":"url","stateCode":"TS"},{"id":4,"title":"TAMILNADU","image":"url","stateCode":"TN"},{"id":3,"title":"KARNATAKA","image":"url","stateCode":"KN"},{"id":2,"title":"ANDHRA","image":"url","stateCode":"AP"}]
Here code to get data===>
const [states, setStates] = useState([]);
useEffect(() => {
handleGetStates()
}, []);
const handleGetStates = async () => {
let values = {
url: `url`,
method: 'get',
}
try {
const response = await axios(values)
setStates(response.data)
console.log(response.data,'response');
} catch (error) {
// handle error
console.log(error);
}
};
You can filter on the array returned from the API:
...
const response = await axios( values );
setStates( response.data.filter(state => state.title === 'KARNATAKA' );
// result: [ {"id":3,"title":"KARNATAKA","image":"url","stateCode":"KN"} ]
...
This will loop through the response and only keep states that have a title of "KARNATAKA"
You can use an array filter method
const {data} = await axios(values);
const result = data?.filter(el=>el.stateCode==='KN')
I don't understand a very simple task, I made a request from a API with axios in react.
If I console log the res.data, is like 170 result of single objects on my console.
I need to convert all these result in a single array of objects.
It's a basic task but I don't understand how to do it.
The application is a Trello Clone.
I have a variable called board that has all the data and with this list request, I grab all the column the the trello and append to ListObjects [] in newBoardData (it's a clone of board)
Here is my code:
//Get Request
const getList = async (id) => {
try {
return await axios.get(`${ENDPOINT}/lists/${id}`);
} catch (err) {
console.log(err);
}
};
const [loading, setLoading] = useState(false);
// Use Effect for grab the data with the listId
useEffect(() => {
(async () => {
setLoading(true);
const res = await (getList(listId));
//Loading up the listObjects
const oldList = board.board.listObjects
const newList = []
const payload = res.data;
//Adding all the old values to the new list (except for the current payload id)
for(let obj of oldList){
if(obj._id !== payload._id) newList.push(obj)
}
//Adding the current payload id
newList.push(payload)
const data = {
...board,
board: {...board.board, listObjects: newList}
};
setList(res.data);
// Here I put the data objects with the new ListObjects Array
setBoardNew(data);
setLoading(false);
})();
}, []);
Here is the console log of the get request res.data:
console.log of res.data
here is the board object:
board object
You can saw that there is a spam of result with the current res.data in ListObjects
I'think it make a request for every card in every list.
thank you very much!
UPDATE:
I will explain how the app works:
I have a file called Board.js, where I make this call (in the console log I have two call if I have two columns):
try {
return await axios.get(`${ENDPOINT}/boards/${id}`);
} catch (err) {
console.log(err);
}
};
useEffect(() => {
(async () => {
setLoading(true);
const res = await (getUserBoard(match.params.id));
if (res) {
axios.defaults.headers.common['boardId'] = match.params.id;
} else {
delete axios.defaults.headers.common['boardId'];
}
const payload = { ...res.data, listObjects: [], cardObjects: [] };
const data = {
...state,
board: { ...state.board, ...payload },
};
setBoardData(data);
setLoading(false);
})();
}, []);
Then I send the props data to the file List.js
{board.board.lists.map((listId, index) => (
<List key={listId} listId={listId} index={index} board={board} />
The list file send the data to
card.js
{list.cards.map((cardId, index) => (
<Card key={cardId} cardId={cardId} list={list} index={index} board={boardNew} />
The logic is: There is the board(board.js), in the board there are the lists (column)(list.js) in the lists there are the cards (card.js)
I hope it's more clear.
simple use this approach to add your new id value into the array state.
this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array
Hello i have some problem with json filtration
when i print jsonArray without id (jsonArray) prints the object to me normally but when i add .id (jsonArray.id) its says undefined What am I doing wrong?
the object i gets with jsonArray and i want to print only 'id' of it
{id: 39497866969165, product_id: 6677529493581, title: '8', price: '181.50'}
const api_url= 'https://eu.kith.com/collections/kith-mlb-for-clarks-originals/products/ck26166616.json'
async function getID() {
const response = await fetch(api_url);
const data = await response.json();
const findsize = data.product.variants
const jsonArray = findsize.filter(function(ele){
return ele.title == "8";
});
console.log(jsonArray.id)
}
getID();
jsonArray is array not object. And getID is a async function. It will return promise. You need to call then to get result.
const api_url = 'https://eu.kith.com/collections/kith-mlb-for-clarks-originals/products/ck26166616.json'
async function getID() {
const response = await fetch(api_url);
const data = await response.json();
const findsize = data.product.variants
const jsonArray = findsize.filter(function(ele) {
return ele.title == "8";
});
const tmp_obj = {
id: jsonArray[0].id,
product_id: jsonArray[0].product_id,
title: jsonArray[0].title,
price: jsonArray[0].price
}
//console.log(tmp_obj)
return tmp_obj
}
getID().then(result => console.log(result));
It's because jsonArray here is a list and not a single object.
First check it's length to make sure there's atleast one object after the filter and log the first element via:
if (jsonArray.length > 0) {
console.log(jsonArray[0].id)
}