score:2
get()
returns a promise
, which is used for asynchronous code.
the
then()
method returns a promise. it takes up to two arguments: callback functions for the success and failure cases of the promise.
therefore the console.log(posts);
outside the then
method will return undefined since the data is not retrieved yet. you need to do the following:
const getposts = () => {
const posts = [];
firestore.collection(`posts`).get().then((snapshot) => {
snapshot.docs.foreach((doc) => {
let data = { ...doc.data() };
posts.unshift(data);
console.log(posts);
console.log(posts[1]);
});
});
};
if you want to access the array outside the then()
method then you can return a promise
:
const getposts = () => {
const posts = [];
return new promise((resolve, reject) => {
firestore.collection(`posts`).get().then((snapshot) => {
snapshot.docs.foreach((doc) => {
let data = { ...doc.data() };
posts.unshift(data);
console.log(posts);
resolve(posts);
console.log(posts[1]);
});
});
});
};
then you can do the following:
getposts().then((posts) => {
console.log(posts);
});
check the following links:
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/promise
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/promise/then
score:2
i would recommend in general to avoid mutating the array using push. that said, you could return the posts from the function so it is easier to work with them
const getposts = async () => {
const snapshot = await firestore.collection('posts').get();
return snapshot.docs.map(snap => object.assign({}, { ...snap.data() }))
}
the await keyword will delay the execution of the code that depends on "snapshot" until the promise is resolved.
edit i put it in its original form again as it is concise and readable. the problem is that the getpost func should be awaited too, because if you do something like:
const posts = getposts()
it would be used immediately and not wait for the getpost() to finish. you can use a .then if you want in getposts, e.g:
getposts().then(result => console.log(result))
you could also wrap the function that uses the getposts() in an async/await and be able to use its results as it were a sync function.
refer here for a related question and another explanation, and also fo the other answers in this same question.
score:3
you have introduced asynchronous code here.
firestore.collection(`posts`).get().then((snapshot) => {
snapshot.docs.foreach((doc) => {
let data = { ...doc.data() };
posts.unshift(data);
});
});
the get() method returns a promise, which will be handled inside .then() method once it gets resolved. that means, only the contents inside the then() will wait for its execution to finish and any thing outside of the block will be executed synchronously.
in your case, all console.log() methods will get executed before you actually get data from the fire base. to fix it you can either manipulate the data inside the then() method like peter said or you can make use of async/await.
example:
var promise1 = new promise(function(resolve, reject) {
settimeout(function() {
resolve('foo');
}, 300);
});
const consoleit = async () => { // returns a promise implicitly
value = await promise1;
console.log('value',value)
}
consoleit(); // expected output: "value" "foo"
//or
const consoleit2 = async () => { // returns a promise implicitly
value = await promise1;
return value;
}
consoleit2().then(value => console.log('value', value)); // expected output: "value" "foo"
your code should be:
const getposts = async () => {
const posts = [];
let snapshot = await firestore.collection(`posts`).get(); // rest of the code will wait for the snapshot value.
snapshot.docs.foreach((doc) => {
let data = { ...doc.data() };
posts.unshift(data);
});
console.log(posts);
console.log(posts.length);
console.log(posts[1]); // will print the object.
return posts;
};
async functions usually returns promise. you can call this function like
const posts = await getposts();
or
getposts().then((posts)=> {console.log(posts)})
your code should be like this
const postslist = () => {
getposts().then((posts) => {
console.log(posts); // prints object
return posts.map((post) => <postitem key={post.id} event={post} />); };
});
// or if you want to handle no data.
let posts = null;
const postslist = () => {
getposts().then((res) => {
post = res;
console.log(posts); // prints object
});
return posts? posts.map((post) => <postitem key={post.id} event={post} />) : <nodata/>;
}
note : await keyword should only be used inside an async function!
Source: stackoverflow.com
Related Query
- Problem when I try to get collection from Firestore
- I get data from Api but when I try to set the value with useState it give me an empty object
- Invalid hook call in class component when I try to use useParams to get the param from url
- Get all documents from collection on Firestore and store into array then print fields
- When i try to call the api data from axios i get 404 error
- An error occurred when I get a data from firestore in React app
- Get document from collection using specific field in firestore
- I keep getting [object Object]. when I try to get data from the map function
- I GET array from API but when i try show it in the table it show me empty array (noob ReactJs)
- react net::ERR_CONNECTION_REFUSED when try to GET data from backend node on localhost
- How to get a collection from firestore which is a Regular Expression?
- React Typescript: Problem when i try to send history argument from a component to an action using withRouter
- Unexpected use of 'event' no-restricted-globals when using event.target.id to get id from bind(this)
- Getting error when try to use React Router v6: Attempted import error: 'Action' is not exported from 'history'
- I get TypeError: Enzyme::Selector expects a string, object, or Component Constructor when I try to test react-bootstrap component
- How to get subcollection from firestore using react-redux-firebase
- React App: Why I get an error when I try to run npm start script?
- Cloudinary image upload from React: am including Cloudinary unsigned preset but get "Upload preset must be specified when using unsigned upload"
- React - Typescript interfaces - errors when get props from union types
- How do I get document and nested collection in a document in a Cloud Firestore collection using Version 9 of the Modular Web SDK?
- Why axios GET error when downloading json file from remote AWS S3 server
- Problem with request from Subcollection in Firestore
- How do I pass the text data from firestore inside the expandable row and get the document ID to be passed inside the setState?
- React Webpack. Why do I get an error when calling a function from a child component?
- How to get data from an API only once when the page is loaded using axios.get method?
- browser says " request has been blocked by CORS policy" when calling to a spring boot get method from react js using axios
- I get a contextTypes error when I try to test a very simple component
- Newbie trying a react.js project. When I try to import an image I get an error message that it failed to compile
- Failed to compile node module when i try to export db from firebase
- "Property does not exist on type 'never'" when i try to access a json data from API response
More Query from same tag
- Import aliases not working as expected in creat-react-app with craco
- Adding two kebab case css class in an element in react
- How to integrate react-draft-wysiwyg custom component with React-Final-Form
- Calling solidity functions to reactJS
- Why is useState within useEffect not working in React?
- UI framework vs Styled-components to make UI from scratch in React?
- How do you pass a parameter to defineMessages in react-intl?
- TypeError: this.setState is not a function, inside Redux Actions file
- Missing Patch method with corsheaders only on chrome
- Faced module not found after I installed bootstrap
- React routes with two parameters not working on react build
- My dapp doesn't detect when an user change their Metamask Account
- Dockerized React App failed to bind to $PORT on Heroku
- How to check for succes/error for a API post in React Saga
- How to Make React Router Resolve within a nested path
- ReactJS component onClick not firing own function
- javascripts default replace function not working in nextjs
- Redux Server Side Rendering: Actions
- Redux-Form separating displayed value and submitted value in custom component
- React JS How to make a Button create another Button
- Using splice in reducer (redux)
- React-Leaflet: Polyline does not change colour despite colour value in Redux store updating
- React - How can I reverse the order of dynamic children lists that have a key unique id
- Why enclose actions returned by Redux action creators in brackets?
- How To Show Data From A Nested Array Using Mongoose Filter?
- Warning: Failed prop type: Invalid prop `defaultValue` of type `string` supplied to `AutoCompleteSearch`, expected `function`
- Requestbody showing undefined in server node.js when attaching form request in react.js
- img element is not working in Ionic React
- React not rendering <th> under loop
- "Log in with Google" JWT is invalid when sent to my server