0

In my RN.js application, I am struggling to display information on the first time that a page loads. To give a quick background, this application is using Prisma and Axios to pull data from a SQL Server. An axios.get(...) request is made to pull a list of objects from the database, and then the resp data is then set to an object that is initialized using a format like setX(resp.data.XList);. To ensure that the query is only run once the user navigates to the page, I used useEffect(() => {...}, []);.

What is odd is that the first time a user tries to load this page, they are met with an error since resp.data.XList prints out in the console as Array []. If the user then swipes back and navigates to the page for a second time, everything that should load does load.

I believe this is an issue with not having some async functionality where it is needed, causing the setX(...) function to be called before the resp data is returned.

To attempt to resolve this, I have tried to create a function that initializes a Promise object and delays for 1 second between when.then((resp) ... ) is called and setX(resp.data.XList) is called. This did not fix it

Another attempt I made was to use a JWT header to require the get request to check that the user's token (session variable) was still valid in a nice async way. This helps to verify that some of the code within the get request will run without error. This did not fix it either.

So, without further ado, here are my loadDataOnlyOnce() and delay() functions as well as some example UI code: (code has been re-formatted for security reasons. Apologies for not being immediately reproducable)

const [data, setData] = useState([]);

function delay(time)
{
   return new Promise(resolve => setTimeout(resolve, time));
}

useEffect(() => {
   loadDataOnlyOnce(); //Fires only on first render
}, []);

const loadDataOnlyOnce = () => {
        SecureStore.getItemAsync("TOKEN").then(x => {
            axios.get(`${baseUrl}/user/pullData`, {
              headers: {
                'Authorization': `JWT ${x}` 
              }
            }).then((resp) => {
                delay(1000).then(() => {
                    if(resp.data.DataList === undefined){ //Navigates user to page where they can push data to DB. New user wont have any data here.
                        Alert.alert('Add Data', 'Please Add Data', [
                            { text: 'OK', onPress: () => { props.navigation.navigate("AddData")}},
                          ]);
                    } else{
                        setData(resp.data.DataList) 
                        console.log(data)
                    }
                });
              }).catch((err) => {
                Alert.alert('Error', err.response.data.message, [
                  { text: 'OK' }
                ]);
              });
            });
    };

return(
 <View>
    {data.map(({parameter1, parameter2, id}) => (
        <DisplayX parameter1={parameter1} parameter2={parameter2} key={id}/>
    ))}
</View>
);

Note: data.map is used to dynamically display the list of objects returned from the get request. <DisplayX ... /> is a component that displays the different parameters of data

Any suggestions would be much appreciated! Thanks!

  • React state updates are asynchronously processed, so you can't console log the state *immediately after* enqueueing the update and expect to see the updated state value. I also see no point or purpose for this `delay` function or nested Promise chain, just access the resolved `resp` value from the axios GET request and enqueue the state update. – Drew Reese May 04 '22 at 21:33
  • @DrewReese Got it, no delay function. Could you further elaborate on "enqueue the state update? When I access the resolved `resp` on the first page load, it is `undefined`, which is not what I want to use. – DumboScript May 04 '22 at 22:30
  • Are you saying that `axios.get(\`${baseUrl}/user/pullData\`, ...)` returns a undefined response value? If so, this would seem to indicate an issue with your API/server if it's supposed to return a response value. Can you clarify exactly where you are seeing it undefined? – Drew Reese May 04 '22 at 22:41
  • @DrewReese Yes it is returning undefined on the first page load, but then once reloaded it contains the correct data. It does not seem like there is an issue with my API/Server since I can see that it grabs the data in a console even though it might not be loaded on the page. – DumboScript May 04 '22 at 22:57
  • @DrewReese Sorry for the confusion there. In logging what `resp` returns, all of the information is there within `resp.data.DataList`. my `const data` is what seems to be undefined. – DumboScript May 05 '22 at 00:56
  • I see. Can you share what the value of `resp.data.DataList` is that the `data` state is updated to? I don't see where `data` can be undefined other than if `resp.data.DataList` is undefined when you enqueue a state update. – Drew Reese May 05 '22 at 01:05

0 Answers0