0

In my mongoDB I have documents with nested objects that corresponds to which make, model and year of the motorbike they fit to. Example:

fits: {
   honda: {
       crf250: {
           1990: true,
           1991: true
       },
       rx400: {
           2000: true
       }
   },
   kawasaki: {
       ninja: {
           2015: true
       }
   }
}

I need to loop through all the makes that the document stores in fits field (In the example above it would be honda and kawasaki) and than return all the models that exist under the specific make. I am succesfully receiving the array of all the models under the make in my aggregate method.

return(
        <ul style={{listStyleType: 'none'}}>
            {Object.keys(props.data.fits).map((make, i) => {
                if(db !== null && client !== null){
                    var query = `fits.${make}`;
                    var pipeline = [
                        {
                            $match: {
                                [query]: { 
                                    '$exists': true,
                                    '$ne': {} 
                                }
                            },
                        },
                        {
                            $group: {
                                _id: `$${query}`,
                            }
                        }
                    ]
                    client.auth.loginWithCredential(new AnonymousCredential()).then((user) => {
                        db.collection('products').aggregate(pipeline).toArray().then((models)=>{
                            return <Make 
                                style={{border: '1px solid grey'}}
                                mongoClient={props.mongoClient}
                                id={props.data._id} 
                                key={i} 
                                make={make} 
                                data={props.data}
                                _handleDeleteMake={handleDeleteMake}
                                _updateRowData={props._updateRowData}
                                _models={models}
                            >
                            </Make>
                        }).catch(e=>console.log(e))
                    })
                    
                }
            })}
        </ul>
    )

However after the call I need to render the makes. It should look something like this:

Next to the orange plus I want to show the list of all the other models that exists under the specific make so I don't have to repeat in writing the model again if its exists already and I can just click on it.

However rendering Make inside the async I am left with blank: enter image description here

Now from what I understand is that the render finished before the async function finished that is why it simply renders empty list, but I don't really know how should I approach this problem. Any suggestions?

1 Answer 1

1

I don't think it's possible for you to render a React element in that async way. When React try to render your element that is inside the ul tags, because you are using async, at the time of DOM painting, there is nothing for React to render. Thus React render blank.

After the async is resolved, React won't re-render because React doesn't know that there is a new element being added in. Thus even when you actually have that element, since React doesn't re-render, you won't see that element in the app

Why does this happen? Because React only re-render when there are certain "signal" that tells React to re-render. Such is state change, props change, hooks call, etc. What you did doesn't fall into any of those categories, so React won't re-render. This is the same reason why you don't directly change the component state and instead must use method like setState to change it.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, makes sense. I thought of another approach where instead of getting all the models this way I would load them after clicking on Model selector next to the orange plus button. In a way it would be actually better since it would only load the models from the specific make rather than models from all makes at once.
Also please don't fetch data directly from inside the return statement. The return statement shall be pure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.