React Native: Reach-Navigation and Pouch-DB - db.put not done before “refresh” callback is run












0















Relative newbie; forgive me if my etiquette and form here aren't great. I'm open to feedback.



I have used create-react-native-app to create an application using PouchDB (which I believe ultimately uses AsyncStorage) to store a list of "items" (basically).



Within a TabNavigator (main app) I have a StackNavigator ("List screen") for the relevant portion of the app. It looks to the DB and queries for the items and then I .map() over each returned record to generate custom ListView-like components dynamically. If there are no records, it alternately displays a prompt telling the user so. In either case, there is an "Add Item" TouchableOpacity that takes them to a screen where they an add a new item (for which they are taken to an "Add" screen).



When navigating back from the "Add" screen I'm using a pattern discussed quite a bit here on SO in which I've passed a "refresh" function as a navigation param. Once the user uses a button on the "Add" screen to "save" the changes, it then does a db.post() and adds them item, runs the "refresh" function on the "List screen" and then navigates back like so:



<TouchableOpacity
style={styles.myButton}
onPress={() => {
if (this.state.itemBrand == '') {
Alert.alert(
'Missing Information',
'Please be sure to select a Brand',
[
{text: 'OK', onPress: () =>
console.log('OK pressed on AddItemScreen')},
],
{ cancelable: false }
)
} else {
this.createItem();
this.props.navigation.state.params.onGoBack();
this.props.navigation.navigate('ItemsScreen');
}
}
}
>


And all of this works fine. The "refresh" function (passed as onGoBack param) works fine... for this screen. The database is called with the query, the new entry is found and the components for the item renders up like a charm.



Each of the rendered ListItem-like components on the "List screen" contains a react-native-slideout with an "Edit" option. An onPress for these will send the user to an "Item Details" screen, and the selected item's _id from PouchDB is passed as a prop to the "Item Details" screen where loadItem() runs in componentDidMount and does a db.get(id) in the database module. Additional details are shown from a list of "events" property for that _id (which are objects, in an array) which render out into another bunch of ListItem-like components.



The problem arises when either choose to "Add" an event to the list for the item... or Delete it (using another function via [another] slideout for these items. There is a similar backward navigation, called in the same form as above after either of the two functions is called from the "Add Event" screen, this being the "Add" example:



async createEvent() {
var eventData = {
eventName: this.state.eventName.trim(),
eventSponsor: this.state.eventSponsor.trim(),
eventDate: this.state.eventDate,
eventJudge: this.state.eventJudge.trim(),
eventStandings: this.state.eventStandings.trim(),
eventPointsEarned: parseInt(this.state.eventPointsEarned.trim()),
};

var key = this.key;
var rev = this.rev;
await db.createEvent(key, rev, eventData);
}


which calls my "db_ops" module function:



exports.createEvent = function (id, rev, eventData) { 
console.log('You called db.createEvent()');
db.get(id)
.then(function(doc) {
var arrWork = doc.events; //assign array of events to working variable
console.log('arrWork is first assigned: ' + arrWork);
arrWork.push(eventData);
console.log('then, arrWork was pushed and became: ' + arrWork);

var arrEvents = arrWork.sort((a,b)=>{
var dateA = new Date(a.eventDate), dateB = new Date(b.eventDate);
return b.eventDate - a.eventDate;
})
doc.events = arrEvents;

return db.put(doc);
})
.then((response) => {
console.log("db.createEvent() response was:n" +
JSON.stringify(response));
})
.catch(function(err){
console.log("Error in db.createEvent():n" + err);
});
}


After which the "Add Event" screen's button fires the above in similar sequence to the first, just before navigating back:



this.createEvent();
this.props.navigation.state.params.onGoBack();
this.props.navigation.navigate('ItemsDetails');


The "refresh" function looks like so (also called in componentDidMount):



    loadItem() {
console.log('Someone called loadItem() with this.itemID of ' + this.itemID);
var id = this.itemID;
let totalWon = 0;
db.loadItem(id)
.then((item) => {
console.log('[LOAD ITEM] got back data of:n' + JSON.stringify(item));
this.setState({objItem: item, events: item.events});

if (this.state.events.length != 0) { this.setState({itemLoaded: true});
this.state.events.map(function(event) {
totalWon += parseInt(event.eventPointsEarned);
console.log('totalWon is ' + totalWon + ' with ' +
event.eventPointsEarned + ' having been added.');
});
};
this.setState({totalWon: totalWon});
})
.catch((err) => {
console.log('db.loadItem() error: ' + err);
this.setState({itemLoaded: false});
});
}


I'm at a loss for why the List Screen refreshes when I add an item... but not when I'm doing other async db operations with PouchDB in what I think is similar fashion to modify the object containing the "event" information and then heading back to the Item Details screen.



Am I screwing up with Promise chain someplace? Neglecting behavior of the StackNavigator when navigating deeper?



The only other difference being that I'm manipulating the array in the db function in the non-working case, whereas the others I'm merely creating/posting or deleting/removing the record, etc. before going back to update state on the prior screen.



Edit to add, as per comments, going back to "List screen" and the opening "Item Details" does pull the database data and correctly shows that the update was made.



Further checking I've done also revealed that the console.log in createEvent() to print the response to the db call isn't logging until after some of the other dynamic rendering methods are getting called on the "Item Details" screen. So it seems as though the prior screen is doing the get() that loadItem() calls before the Promise chain in createEvent() is resolving. Whether the larger issue is due to state management is still unclear -- though it would make sense in some respects -- to me as this could be happening regardless of whether I've called my onGoBack() function.



Edit/bump: I’ve tried to put async/await to use in various places in both the db_ops module on the db.get() and the component-side loadItem() which calls it. There’s something in the timing of these that just doesn’t jive and I am just totally stuck here. Aside from trying out redux (which I think is overkill in this particular case), any ideas?










share|improve this question





























    0















    Relative newbie; forgive me if my etiquette and form here aren't great. I'm open to feedback.



    I have used create-react-native-app to create an application using PouchDB (which I believe ultimately uses AsyncStorage) to store a list of "items" (basically).



    Within a TabNavigator (main app) I have a StackNavigator ("List screen") for the relevant portion of the app. It looks to the DB and queries for the items and then I .map() over each returned record to generate custom ListView-like components dynamically. If there are no records, it alternately displays a prompt telling the user so. In either case, there is an "Add Item" TouchableOpacity that takes them to a screen where they an add a new item (for which they are taken to an "Add" screen).



    When navigating back from the "Add" screen I'm using a pattern discussed quite a bit here on SO in which I've passed a "refresh" function as a navigation param. Once the user uses a button on the "Add" screen to "save" the changes, it then does a db.post() and adds them item, runs the "refresh" function on the "List screen" and then navigates back like so:



    <TouchableOpacity
    style={styles.myButton}
    onPress={() => {
    if (this.state.itemBrand == '') {
    Alert.alert(
    'Missing Information',
    'Please be sure to select a Brand',
    [
    {text: 'OK', onPress: () =>
    console.log('OK pressed on AddItemScreen')},
    ],
    { cancelable: false }
    )
    } else {
    this.createItem();
    this.props.navigation.state.params.onGoBack();
    this.props.navigation.navigate('ItemsScreen');
    }
    }
    }
    >


    And all of this works fine. The "refresh" function (passed as onGoBack param) works fine... for this screen. The database is called with the query, the new entry is found and the components for the item renders up like a charm.



    Each of the rendered ListItem-like components on the "List screen" contains a react-native-slideout with an "Edit" option. An onPress for these will send the user to an "Item Details" screen, and the selected item's _id from PouchDB is passed as a prop to the "Item Details" screen where loadItem() runs in componentDidMount and does a db.get(id) in the database module. Additional details are shown from a list of "events" property for that _id (which are objects, in an array) which render out into another bunch of ListItem-like components.



    The problem arises when either choose to "Add" an event to the list for the item... or Delete it (using another function via [another] slideout for these items. There is a similar backward navigation, called in the same form as above after either of the two functions is called from the "Add Event" screen, this being the "Add" example:



    async createEvent() {
    var eventData = {
    eventName: this.state.eventName.trim(),
    eventSponsor: this.state.eventSponsor.trim(),
    eventDate: this.state.eventDate,
    eventJudge: this.state.eventJudge.trim(),
    eventStandings: this.state.eventStandings.trim(),
    eventPointsEarned: parseInt(this.state.eventPointsEarned.trim()),
    };

    var key = this.key;
    var rev = this.rev;
    await db.createEvent(key, rev, eventData);
    }


    which calls my "db_ops" module function:



    exports.createEvent = function (id, rev, eventData) { 
    console.log('You called db.createEvent()');
    db.get(id)
    .then(function(doc) {
    var arrWork = doc.events; //assign array of events to working variable
    console.log('arrWork is first assigned: ' + arrWork);
    arrWork.push(eventData);
    console.log('then, arrWork was pushed and became: ' + arrWork);

    var arrEvents = arrWork.sort((a,b)=>{
    var dateA = new Date(a.eventDate), dateB = new Date(b.eventDate);
    return b.eventDate - a.eventDate;
    })
    doc.events = arrEvents;

    return db.put(doc);
    })
    .then((response) => {
    console.log("db.createEvent() response was:n" +
    JSON.stringify(response));
    })
    .catch(function(err){
    console.log("Error in db.createEvent():n" + err);
    });
    }


    After which the "Add Event" screen's button fires the above in similar sequence to the first, just before navigating back:



    this.createEvent();
    this.props.navigation.state.params.onGoBack();
    this.props.navigation.navigate('ItemsDetails');


    The "refresh" function looks like so (also called in componentDidMount):



        loadItem() {
    console.log('Someone called loadItem() with this.itemID of ' + this.itemID);
    var id = this.itemID;
    let totalWon = 0;
    db.loadItem(id)
    .then((item) => {
    console.log('[LOAD ITEM] got back data of:n' + JSON.stringify(item));
    this.setState({objItem: item, events: item.events});

    if (this.state.events.length != 0) { this.setState({itemLoaded: true});
    this.state.events.map(function(event) {
    totalWon += parseInt(event.eventPointsEarned);
    console.log('totalWon is ' + totalWon + ' with ' +
    event.eventPointsEarned + ' having been added.');
    });
    };
    this.setState({totalWon: totalWon});
    })
    .catch((err) => {
    console.log('db.loadItem() error: ' + err);
    this.setState({itemLoaded: false});
    });
    }


    I'm at a loss for why the List Screen refreshes when I add an item... but not when I'm doing other async db operations with PouchDB in what I think is similar fashion to modify the object containing the "event" information and then heading back to the Item Details screen.



    Am I screwing up with Promise chain someplace? Neglecting behavior of the StackNavigator when navigating deeper?



    The only other difference being that I'm manipulating the array in the db function in the non-working case, whereas the others I'm merely creating/posting or deleting/removing the record, etc. before going back to update state on the prior screen.



    Edit to add, as per comments, going back to "List screen" and the opening "Item Details" does pull the database data and correctly shows that the update was made.



    Further checking I've done also revealed that the console.log in createEvent() to print the response to the db call isn't logging until after some of the other dynamic rendering methods are getting called on the "Item Details" screen. So it seems as though the prior screen is doing the get() that loadItem() calls before the Promise chain in createEvent() is resolving. Whether the larger issue is due to state management is still unclear -- though it would make sense in some respects -- to me as this could be happening regardless of whether I've called my onGoBack() function.



    Edit/bump: I’ve tried to put async/await to use in various places in both the db_ops module on the db.get() and the component-side loadItem() which calls it. There’s something in the timing of these that just doesn’t jive and I am just totally stuck here. Aside from trying out redux (which I think is overkill in this particular case), any ideas?










    share|improve this question



























      0












      0








      0








      Relative newbie; forgive me if my etiquette and form here aren't great. I'm open to feedback.



      I have used create-react-native-app to create an application using PouchDB (which I believe ultimately uses AsyncStorage) to store a list of "items" (basically).



      Within a TabNavigator (main app) I have a StackNavigator ("List screen") for the relevant portion of the app. It looks to the DB and queries for the items and then I .map() over each returned record to generate custom ListView-like components dynamically. If there are no records, it alternately displays a prompt telling the user so. In either case, there is an "Add Item" TouchableOpacity that takes them to a screen where they an add a new item (for which they are taken to an "Add" screen).



      When navigating back from the "Add" screen I'm using a pattern discussed quite a bit here on SO in which I've passed a "refresh" function as a navigation param. Once the user uses a button on the "Add" screen to "save" the changes, it then does a db.post() and adds them item, runs the "refresh" function on the "List screen" and then navigates back like so:



      <TouchableOpacity
      style={styles.myButton}
      onPress={() => {
      if (this.state.itemBrand == '') {
      Alert.alert(
      'Missing Information',
      'Please be sure to select a Brand',
      [
      {text: 'OK', onPress: () =>
      console.log('OK pressed on AddItemScreen')},
      ],
      { cancelable: false }
      )
      } else {
      this.createItem();
      this.props.navigation.state.params.onGoBack();
      this.props.navigation.navigate('ItemsScreen');
      }
      }
      }
      >


      And all of this works fine. The "refresh" function (passed as onGoBack param) works fine... for this screen. The database is called with the query, the new entry is found and the components for the item renders up like a charm.



      Each of the rendered ListItem-like components on the "List screen" contains a react-native-slideout with an "Edit" option. An onPress for these will send the user to an "Item Details" screen, and the selected item's _id from PouchDB is passed as a prop to the "Item Details" screen where loadItem() runs in componentDidMount and does a db.get(id) in the database module. Additional details are shown from a list of "events" property for that _id (which are objects, in an array) which render out into another bunch of ListItem-like components.



      The problem arises when either choose to "Add" an event to the list for the item... or Delete it (using another function via [another] slideout for these items. There is a similar backward navigation, called in the same form as above after either of the two functions is called from the "Add Event" screen, this being the "Add" example:



      async createEvent() {
      var eventData = {
      eventName: this.state.eventName.trim(),
      eventSponsor: this.state.eventSponsor.trim(),
      eventDate: this.state.eventDate,
      eventJudge: this.state.eventJudge.trim(),
      eventStandings: this.state.eventStandings.trim(),
      eventPointsEarned: parseInt(this.state.eventPointsEarned.trim()),
      };

      var key = this.key;
      var rev = this.rev;
      await db.createEvent(key, rev, eventData);
      }


      which calls my "db_ops" module function:



      exports.createEvent = function (id, rev, eventData) { 
      console.log('You called db.createEvent()');
      db.get(id)
      .then(function(doc) {
      var arrWork = doc.events; //assign array of events to working variable
      console.log('arrWork is first assigned: ' + arrWork);
      arrWork.push(eventData);
      console.log('then, arrWork was pushed and became: ' + arrWork);

      var arrEvents = arrWork.sort((a,b)=>{
      var dateA = new Date(a.eventDate), dateB = new Date(b.eventDate);
      return b.eventDate - a.eventDate;
      })
      doc.events = arrEvents;

      return db.put(doc);
      })
      .then((response) => {
      console.log("db.createEvent() response was:n" +
      JSON.stringify(response));
      })
      .catch(function(err){
      console.log("Error in db.createEvent():n" + err);
      });
      }


      After which the "Add Event" screen's button fires the above in similar sequence to the first, just before navigating back:



      this.createEvent();
      this.props.navigation.state.params.onGoBack();
      this.props.navigation.navigate('ItemsDetails');


      The "refresh" function looks like so (also called in componentDidMount):



          loadItem() {
      console.log('Someone called loadItem() with this.itemID of ' + this.itemID);
      var id = this.itemID;
      let totalWon = 0;
      db.loadItem(id)
      .then((item) => {
      console.log('[LOAD ITEM] got back data of:n' + JSON.stringify(item));
      this.setState({objItem: item, events: item.events});

      if (this.state.events.length != 0) { this.setState({itemLoaded: true});
      this.state.events.map(function(event) {
      totalWon += parseInt(event.eventPointsEarned);
      console.log('totalWon is ' + totalWon + ' with ' +
      event.eventPointsEarned + ' having been added.');
      });
      };
      this.setState({totalWon: totalWon});
      })
      .catch((err) => {
      console.log('db.loadItem() error: ' + err);
      this.setState({itemLoaded: false});
      });
      }


      I'm at a loss for why the List Screen refreshes when I add an item... but not when I'm doing other async db operations with PouchDB in what I think is similar fashion to modify the object containing the "event" information and then heading back to the Item Details screen.



      Am I screwing up with Promise chain someplace? Neglecting behavior of the StackNavigator when navigating deeper?



      The only other difference being that I'm manipulating the array in the db function in the non-working case, whereas the others I'm merely creating/posting or deleting/removing the record, etc. before going back to update state on the prior screen.



      Edit to add, as per comments, going back to "List screen" and the opening "Item Details" does pull the database data and correctly shows that the update was made.



      Further checking I've done also revealed that the console.log in createEvent() to print the response to the db call isn't logging until after some of the other dynamic rendering methods are getting called on the "Item Details" screen. So it seems as though the prior screen is doing the get() that loadItem() calls before the Promise chain in createEvent() is resolving. Whether the larger issue is due to state management is still unclear -- though it would make sense in some respects -- to me as this could be happening regardless of whether I've called my onGoBack() function.



      Edit/bump: I’ve tried to put async/await to use in various places in both the db_ops module on the db.get() and the component-side loadItem() which calls it. There’s something in the timing of these that just doesn’t jive and I am just totally stuck here. Aside from trying out redux (which I think is overkill in this particular case), any ideas?










      share|improve this question
















      Relative newbie; forgive me if my etiquette and form here aren't great. I'm open to feedback.



      I have used create-react-native-app to create an application using PouchDB (which I believe ultimately uses AsyncStorage) to store a list of "items" (basically).



      Within a TabNavigator (main app) I have a StackNavigator ("List screen") for the relevant portion of the app. It looks to the DB and queries for the items and then I .map() over each returned record to generate custom ListView-like components dynamically. If there are no records, it alternately displays a prompt telling the user so. In either case, there is an "Add Item" TouchableOpacity that takes them to a screen where they an add a new item (for which they are taken to an "Add" screen).



      When navigating back from the "Add" screen I'm using a pattern discussed quite a bit here on SO in which I've passed a "refresh" function as a navigation param. Once the user uses a button on the "Add" screen to "save" the changes, it then does a db.post() and adds them item, runs the "refresh" function on the "List screen" and then navigates back like so:



      <TouchableOpacity
      style={styles.myButton}
      onPress={() => {
      if (this.state.itemBrand == '') {
      Alert.alert(
      'Missing Information',
      'Please be sure to select a Brand',
      [
      {text: 'OK', onPress: () =>
      console.log('OK pressed on AddItemScreen')},
      ],
      { cancelable: false }
      )
      } else {
      this.createItem();
      this.props.navigation.state.params.onGoBack();
      this.props.navigation.navigate('ItemsScreen');
      }
      }
      }
      >


      And all of this works fine. The "refresh" function (passed as onGoBack param) works fine... for this screen. The database is called with the query, the new entry is found and the components for the item renders up like a charm.



      Each of the rendered ListItem-like components on the "List screen" contains a react-native-slideout with an "Edit" option. An onPress for these will send the user to an "Item Details" screen, and the selected item's _id from PouchDB is passed as a prop to the "Item Details" screen where loadItem() runs in componentDidMount and does a db.get(id) in the database module. Additional details are shown from a list of "events" property for that _id (which are objects, in an array) which render out into another bunch of ListItem-like components.



      The problem arises when either choose to "Add" an event to the list for the item... or Delete it (using another function via [another] slideout for these items. There is a similar backward navigation, called in the same form as above after either of the two functions is called from the "Add Event" screen, this being the "Add" example:



      async createEvent() {
      var eventData = {
      eventName: this.state.eventName.trim(),
      eventSponsor: this.state.eventSponsor.trim(),
      eventDate: this.state.eventDate,
      eventJudge: this.state.eventJudge.trim(),
      eventStandings: this.state.eventStandings.trim(),
      eventPointsEarned: parseInt(this.state.eventPointsEarned.trim()),
      };

      var key = this.key;
      var rev = this.rev;
      await db.createEvent(key, rev, eventData);
      }


      which calls my "db_ops" module function:



      exports.createEvent = function (id, rev, eventData) { 
      console.log('You called db.createEvent()');
      db.get(id)
      .then(function(doc) {
      var arrWork = doc.events; //assign array of events to working variable
      console.log('arrWork is first assigned: ' + arrWork);
      arrWork.push(eventData);
      console.log('then, arrWork was pushed and became: ' + arrWork);

      var arrEvents = arrWork.sort((a,b)=>{
      var dateA = new Date(a.eventDate), dateB = new Date(b.eventDate);
      return b.eventDate - a.eventDate;
      })
      doc.events = arrEvents;

      return db.put(doc);
      })
      .then((response) => {
      console.log("db.createEvent() response was:n" +
      JSON.stringify(response));
      })
      .catch(function(err){
      console.log("Error in db.createEvent():n" + err);
      });
      }


      After which the "Add Event" screen's button fires the above in similar sequence to the first, just before navigating back:



      this.createEvent();
      this.props.navigation.state.params.onGoBack();
      this.props.navigation.navigate('ItemsDetails');


      The "refresh" function looks like so (also called in componentDidMount):



          loadItem() {
      console.log('Someone called loadItem() with this.itemID of ' + this.itemID);
      var id = this.itemID;
      let totalWon = 0;
      db.loadItem(id)
      .then((item) => {
      console.log('[LOAD ITEM] got back data of:n' + JSON.stringify(item));
      this.setState({objItem: item, events: item.events});

      if (this.state.events.length != 0) { this.setState({itemLoaded: true});
      this.state.events.map(function(event) {
      totalWon += parseInt(event.eventPointsEarned);
      console.log('totalWon is ' + totalWon + ' with ' +
      event.eventPointsEarned + ' having been added.');
      });
      };
      this.setState({totalWon: totalWon});
      })
      .catch((err) => {
      console.log('db.loadItem() error: ' + err);
      this.setState({itemLoaded: false});
      });
      }


      I'm at a loss for why the List Screen refreshes when I add an item... but not when I'm doing other async db operations with PouchDB in what I think is similar fashion to modify the object containing the "event" information and then heading back to the Item Details screen.



      Am I screwing up with Promise chain someplace? Neglecting behavior of the StackNavigator when navigating deeper?



      The only other difference being that I'm manipulating the array in the db function in the non-working case, whereas the others I'm merely creating/posting or deleting/removing the record, etc. before going back to update state on the prior screen.



      Edit to add, as per comments, going back to "List screen" and the opening "Item Details" does pull the database data and correctly shows that the update was made.



      Further checking I've done also revealed that the console.log in createEvent() to print the response to the db call isn't logging until after some of the other dynamic rendering methods are getting called on the "Item Details" screen. So it seems as though the prior screen is doing the get() that loadItem() calls before the Promise chain in createEvent() is resolving. Whether the larger issue is due to state management is still unclear -- though it would make sense in some respects -- to me as this could be happening regardless of whether I've called my onGoBack() function.



      Edit/bump: I’ve tried to put async/await to use in various places in both the db_ops module on the db.get() and the component-side loadItem() which calls it. There’s something in the timing of these that just doesn’t jive and I am just totally stuck here. Aside from trying out redux (which I think is overkill in this particular case), any ideas?







      node.js react-native promise react-navigation pouchdb






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 4 '18 at 7:31







      NodeNewb

















      asked Nov 23 '18 at 23:41









      NodeNewbNodeNewb

      1315




      1315
























          1 Answer
          1






          active

          oldest

          votes


















          0














          There is nothing to do with PDB or navigation, it's about how you manage outer changes in your depending (already mounted in Navigator since they are in history - it's important to understand - so componentDidMount isn't enough) components. If you don't use global state redux-alike management (as I do) the only way to let know depending component that it should update is passing corresponding props and checking if they were changed.
          Like so:



              //root.js
          refreshEvents = ()=> { //pass it to DeleteView via screenProps
          this.setState({time2refreshEvents: +new Date()}) //pass time2refreshEvents to EventList via screenProps
          }

          //DeleteView.js
          //delete button...
          onPress={db.deleteThing(thingID).then(()=> this.props.screenProps.refreshEvents())}

          //EventList.js
          ...
          constructor(props) {
          super(props);
          this.state = {
          events: ,
          noEvents: false,
          ready: false,
          time2refreshEvents: this.props.screenProps.time2refreshEvents,
          }
          }

          static getDerivedStateFromProps(nextProps, currentState) {
          if (nextProps.screenProps.time2refreshEvents !== currentState.time2refreshEvents ) {
          return {time2refreshEvents : nextProps.screenProps.time2refreshEvents }
          } else {
          return null
          }
          }

          componentDidMount() {
          this._getEvents()
          }

          componentDidUpdate(prevProps, prevState) {
          if (this.state.time2refreshEvents !== prevState.time2refreshEvents) {
          this._getEvents()
          }
          }

          _getEvents = ()=> {
          //do stuff querying db and updating your list with actual data
          }





          share|improve this answer


























          • Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

            – NodeNewb
            Nov 24 '18 at 8:50











          • (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

            – NodeNewb
            Nov 24 '18 at 8:53













          • I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

            – Alex Green
            Nov 24 '18 at 15:27













          • As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

            – NodeNewb
            Dec 4 '18 at 7:09











          • Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

            – NodeNewb
            Dec 4 '18 at 7:13











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453933%2freact-native-reach-navigation-and-pouch-db-db-put-not-done-before-refresh-c%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          There is nothing to do with PDB or navigation, it's about how you manage outer changes in your depending (already mounted in Navigator since they are in history - it's important to understand - so componentDidMount isn't enough) components. If you don't use global state redux-alike management (as I do) the only way to let know depending component that it should update is passing corresponding props and checking if they were changed.
          Like so:



              //root.js
          refreshEvents = ()=> { //pass it to DeleteView via screenProps
          this.setState({time2refreshEvents: +new Date()}) //pass time2refreshEvents to EventList via screenProps
          }

          //DeleteView.js
          //delete button...
          onPress={db.deleteThing(thingID).then(()=> this.props.screenProps.refreshEvents())}

          //EventList.js
          ...
          constructor(props) {
          super(props);
          this.state = {
          events: ,
          noEvents: false,
          ready: false,
          time2refreshEvents: this.props.screenProps.time2refreshEvents,
          }
          }

          static getDerivedStateFromProps(nextProps, currentState) {
          if (nextProps.screenProps.time2refreshEvents !== currentState.time2refreshEvents ) {
          return {time2refreshEvents : nextProps.screenProps.time2refreshEvents }
          } else {
          return null
          }
          }

          componentDidMount() {
          this._getEvents()
          }

          componentDidUpdate(prevProps, prevState) {
          if (this.state.time2refreshEvents !== prevState.time2refreshEvents) {
          this._getEvents()
          }
          }

          _getEvents = ()=> {
          //do stuff querying db and updating your list with actual data
          }





          share|improve this answer


























          • Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

            – NodeNewb
            Nov 24 '18 at 8:50











          • (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

            – NodeNewb
            Nov 24 '18 at 8:53













          • I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

            – Alex Green
            Nov 24 '18 at 15:27













          • As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

            – NodeNewb
            Dec 4 '18 at 7:09











          • Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

            – NodeNewb
            Dec 4 '18 at 7:13
















          0














          There is nothing to do with PDB or navigation, it's about how you manage outer changes in your depending (already mounted in Navigator since they are in history - it's important to understand - so componentDidMount isn't enough) components. If you don't use global state redux-alike management (as I do) the only way to let know depending component that it should update is passing corresponding props and checking if they were changed.
          Like so:



              //root.js
          refreshEvents = ()=> { //pass it to DeleteView via screenProps
          this.setState({time2refreshEvents: +new Date()}) //pass time2refreshEvents to EventList via screenProps
          }

          //DeleteView.js
          //delete button...
          onPress={db.deleteThing(thingID).then(()=> this.props.screenProps.refreshEvents())}

          //EventList.js
          ...
          constructor(props) {
          super(props);
          this.state = {
          events: ,
          noEvents: false,
          ready: false,
          time2refreshEvents: this.props.screenProps.time2refreshEvents,
          }
          }

          static getDerivedStateFromProps(nextProps, currentState) {
          if (nextProps.screenProps.time2refreshEvents !== currentState.time2refreshEvents ) {
          return {time2refreshEvents : nextProps.screenProps.time2refreshEvents }
          } else {
          return null
          }
          }

          componentDidMount() {
          this._getEvents()
          }

          componentDidUpdate(prevProps, prevState) {
          if (this.state.time2refreshEvents !== prevState.time2refreshEvents) {
          this._getEvents()
          }
          }

          _getEvents = ()=> {
          //do stuff querying db and updating your list with actual data
          }





          share|improve this answer


























          • Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

            – NodeNewb
            Nov 24 '18 at 8:50











          • (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

            – NodeNewb
            Nov 24 '18 at 8:53













          • I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

            – Alex Green
            Nov 24 '18 at 15:27













          • As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

            – NodeNewb
            Dec 4 '18 at 7:09











          • Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

            – NodeNewb
            Dec 4 '18 at 7:13














          0












          0








          0







          There is nothing to do with PDB or navigation, it's about how you manage outer changes in your depending (already mounted in Navigator since they are in history - it's important to understand - so componentDidMount isn't enough) components. If you don't use global state redux-alike management (as I do) the only way to let know depending component that it should update is passing corresponding props and checking if they were changed.
          Like so:



              //root.js
          refreshEvents = ()=> { //pass it to DeleteView via screenProps
          this.setState({time2refreshEvents: +new Date()}) //pass time2refreshEvents to EventList via screenProps
          }

          //DeleteView.js
          //delete button...
          onPress={db.deleteThing(thingID).then(()=> this.props.screenProps.refreshEvents())}

          //EventList.js
          ...
          constructor(props) {
          super(props);
          this.state = {
          events: ,
          noEvents: false,
          ready: false,
          time2refreshEvents: this.props.screenProps.time2refreshEvents,
          }
          }

          static getDerivedStateFromProps(nextProps, currentState) {
          if (nextProps.screenProps.time2refreshEvents !== currentState.time2refreshEvents ) {
          return {time2refreshEvents : nextProps.screenProps.time2refreshEvents }
          } else {
          return null
          }
          }

          componentDidMount() {
          this._getEvents()
          }

          componentDidUpdate(prevProps, prevState) {
          if (this.state.time2refreshEvents !== prevState.time2refreshEvents) {
          this._getEvents()
          }
          }

          _getEvents = ()=> {
          //do stuff querying db and updating your list with actual data
          }





          share|improve this answer















          There is nothing to do with PDB or navigation, it's about how you manage outer changes in your depending (already mounted in Navigator since they are in history - it's important to understand - so componentDidMount isn't enough) components. If you don't use global state redux-alike management (as I do) the only way to let know depending component that it should update is passing corresponding props and checking if they were changed.
          Like so:



              //root.js
          refreshEvents = ()=> { //pass it to DeleteView via screenProps
          this.setState({time2refreshEvents: +new Date()}) //pass time2refreshEvents to EventList via screenProps
          }

          //DeleteView.js
          //delete button...
          onPress={db.deleteThing(thingID).then(()=> this.props.screenProps.refreshEvents())}

          //EventList.js
          ...
          constructor(props) {
          super(props);
          this.state = {
          events: ,
          noEvents: false,
          ready: false,
          time2refreshEvents: this.props.screenProps.time2refreshEvents,
          }
          }

          static getDerivedStateFromProps(nextProps, currentState) {
          if (nextProps.screenProps.time2refreshEvents !== currentState.time2refreshEvents ) {
          return {time2refreshEvents : nextProps.screenProps.time2refreshEvents }
          } else {
          return null
          }
          }

          componentDidMount() {
          this._getEvents()
          }

          componentDidUpdate(prevProps, prevState) {
          if (this.state.time2refreshEvents !== prevState.time2refreshEvents) {
          this._getEvents()
          }
          }

          _getEvents = ()=> {
          //do stuff querying db and updating your list with actual data
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 8:38

























          answered Nov 24 '18 at 8:23









          Alex GreenAlex Green

          817




          817













          • Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

            – NodeNewb
            Nov 24 '18 at 8:50











          • (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

            – NodeNewb
            Nov 24 '18 at 8:53













          • I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

            – Alex Green
            Nov 24 '18 at 15:27













          • As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

            – NodeNewb
            Dec 4 '18 at 7:09











          • Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

            – NodeNewb
            Dec 4 '18 at 7:13



















          • Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

            – NodeNewb
            Nov 24 '18 at 8:50











          • (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

            – NodeNewb
            Nov 24 '18 at 8:53













          • I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

            – Alex Green
            Nov 24 '18 at 15:27













          • As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

            – NodeNewb
            Dec 4 '18 at 7:09











          • Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

            – NodeNewb
            Dec 4 '18 at 7:13

















          Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

          – NodeNewb
          Nov 24 '18 at 8:50





          Thanks for the quick response! I'm still trying to wrap my head around what you've shared, though I appreciate that going back and learning how to use redux is probably going to be part of my logical steps forward in the long haul to make the states more 'global' or however one might properly call it. One odd behavior I didn't mention is this: while the "outer" list ("List screen") of items refreshes using the same sort of onGoBack method, this one doesn't. BUT -- if I go back from "Item Details" to the "List Screen", the changes I make in the "Add Event" screen do get pulled from the db.

          – NodeNewb
          Nov 24 '18 at 8:50













          (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

          – NodeNewb
          Nov 24 '18 at 8:53







          (In other words, I just need to tap the item again on the "List Screen" to open the "Item Details" screen again and apparently the data does appear to have written and update -- which is partially why I assume I was making an asynchronous/Promise blunder.) If I understand you -- and your code -- correctly, this is more of an issue with state management.

          – NodeNewb
          Nov 24 '18 at 8:53















          I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

          – Alex Green
          Nov 24 '18 at 15:27







          I guess that, but true is that once component stays mounted by Navigator => no more didMount involved and your code in didMount won't run. So you need explicitly somehow force component to reload it's data. Probably your List screen is being unmounted on some stage so your didMount logic plays a game again. I just didn't notice any code following props change - that's why I made my suggestions

          – Alex Green
          Nov 24 '18 at 15:27















          As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

          – NodeNewb
          Dec 4 '18 at 7:09





          As for ComponentDidMount() only being called once, that was actually the primary reason I factored the loadItems() out into its own separate method... so I could call that method from inside of ComponentDidMount() but also separately (such as passing the separate method in onGoBack()).

          – NodeNewb
          Dec 4 '18 at 7:09













          Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

          – NodeNewb
          Dec 4 '18 at 7:13





          Given that this is deep as this app really needs to go, it didn’t feel like a sensible thing to bloat everything with a redux-type solution (though I have plans for another project that will absolutely require me to use it, so if I must with this I suppose I’ll end up buckling to do it).

          – NodeNewb
          Dec 4 '18 at 7:13


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453933%2freact-native-reach-navigation-and-pouch-db-db-put-not-done-before-refresh-c%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Berounka

          Fiat S.p.A.

          Type 'String' is not a subtype of type 'int' of 'index'