Search code examples
node.jsreact-nativeuse-effectasyncstorage

AsyncStorage before list render React Native


I have an app that list incidents of a animals charity ong.

After the login, the ong is directed to your incidents list, so i must pass your ID of login page to load this list.

I'm trying to load the variables of AsyncStorage in a function and then pass it to a callback that load the incidents list in React useEffect.

Code:

export default function Incidents() {
  const [incidents, setIncidents] = useState([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [id, setID] = useState('');
  const [name, setName] = useState('');

loadStorage:

loadStorage = async function(callback) {
    
    try {
      const ongid = await AsyncStorage.getItem('ongID');
      const ongname = await AsyncStorage.getItem('ongName');

      if (ongid && ongname !== null) {
        setID(ongid);
        setName(ongname);
        
      }
    } catch (e) {
      alert(e);
    }

    callback();
  }

loadIncidents:

loadIncidents = async function() {

    if (loading) {
      return;
    }

    if (total > 0 && incidents.lenght === total) {
      return;
    }

    try {
      const response = await api.get('profiles', {
        headers: {
          Authorization: id,
        },
        params: { page },
      });
  
      setIncidents([ ... incidents, ... response.data]);
      setTotal(response.headers['x-total-count']);
      setPage(page +1);
      setLoading(false);

    } catch (e) {
      alert(e); //When i access the incident list page i got the error: 'Error: Request failed with status code 400'
    }  
  }

useEffect:

useEffect(() => {
    navigation.addListener('focus', () => {
      loadStorage(loadIncidents);
    });
  }, []);

The error in the alert (e) line of loadIncidents happens because useEffect is not fully calling the loadStorage (loadIncidents) part the first time I enter the application.

I have another page called newIncident, if I navigate to it after pressing OK on this error and go back to the incident list page (by navite.goBack ()) the list will be loaded with all the incidents from the logged ONG.

Need this behavior when I first enter the page that lists the ONG's incidents. Since the both methods are asynchronous, i'm not be able to figure out how to do this.


Solution

  • Did it using promises. code below:

    async function loadStorage() {
        var ongid = '';
        var ongname = '';
    
        try {
          ongid = await AsyncStorage.getItem('ongID');
          ongname = await AsyncStorage.getItem('ongName');
    
        } catch (e) {
          alert(e);
        }
    
        return new Promise((resolve, reject) => {
    
          if (ongid !== null) {
            setID(ongid);
            setName(ongname);
            const ong = { 'name': ongname, 'id': ongid}
    
            return resolve(ong);
          }
        })
      }
    

    Then in useEffect information loads like this:

    loadStorage()
     .then(loadIncidents)