0

I have an ionic react app in which I want to show data from a database when the application opens, however the values are only displayed after I navigate to another tab then back to the original one. I will be adding to the database and want the most up to date values to show every time the user navigates to that tab.

I've tried useIonViewWillEnter and useEffect and neither are working the way I want them to.

Is there any way that I can get the values to display upon opening the application then update and display new values every time I navigate to that tab?

This is the page I am trying to render:

const Tab1: React.FC = () => {
  const [loans, setLoans] = useState<Loan[]>()

  useEffect(() => {
    setLoans(getAllLoans())
    console.log(loans)
  }, []);

 
  return (
    <IonPage>
      <IonHeader>
        <IonToolbar color="primary">
          <IonTitle>Select A Loan</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">

        <IonList>
          {loans && loans.map((loan) => <IonItem><IonText>{loan.name} {loan.principle} {loan.interest}</IonText></IonItem>)}
        </IonList>
     
      </IonContent>
    </IonPage>
  );
};

And this is the function I am getting the data from. It returns the array of loans that I want to display:

export const getAllLoans = (): Loan[] => {
  const loans: Loan[] = []
  try {
    SQLite.create({
      name: 'loan.db', location: 'default'
    }).then(async (db: SQLiteObject) => {
        try {
          const create = await db.executeSql("create table if not exists loans(name VARCHAR(32) NOT NULL, principle REAL NOT NULL, interest REAL NOT NULL)", [])
          const query = "SELECT * FROM loans"
          const get = db.executeSql(query, []).then(data => {
            for(let i=0; i < data.rows.length; i++){
              loans.push({
                name: data.rows.item(i).name,
                principle: data.rows.item(i).principle,
                interest: data.rows.item(i).interest
              })
            }
            console.log(loans)
            return loans;
          });
          //console.log('found: '+ loans);
          return loans
        } catch (e) {
          console.log('SQL get error: ', e);
          return loans
        }
    })
  } catch(e) {
    console.log('database get error ', e)
    return loans
  }
  return loans
}
  • 1
    Hello, I suggest you read a bit about promises, especially the chapter **ES2015+ Promises with then()** - https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call. Right now, you are just returning an empty array. – edo.n Aug 09 '20 at 17:44

2 Answers2

0

This may be relevant - React doesn't do deep comparisons on array elements when deciding if a component needs a refresh. Try this --

At the top of the component:

const [toggleRefresh, setToggleRefresh] = useState(false);

Then in the useEffect:

  useEffect(() => {
    setLoans(getAllLoans())
    setToggleRefresh = (!toggleRefresh)
    console.log(loans)
  }, []);

If it works, it means that React doesn't know that the elements of loans have changed and therefore doesn't do a re-render on the component.

VikR
  • 4,818
  • 8
  • 51
  • 96
  • 1
    That's not the problem at all, he is returning an empty array from the getAllLoans() function. – edo.n Aug 09 '20 at 17:43
  • The function returns the correct array, for some reason it just doesn't show up on the first render or change whenever the array is updated. I even tried initializing it using const [loans, setLoans] = useState(getAllLoans()) and the array shows up when I log it. It just refuses to render for some reason – I'm Clueless Aug 09 '20 at 19:51
  • @I'mClueless, did you try my suggestion yet? – VikR Aug 09 '20 at 22:32
  • I tried it, but I'm not completely sure how to implement it. Whenever I try something like this I keep getting stuck in an infinite loop because the page keeps refreshing. The only way I've ever gotten the array to display is if I move to a different tab then come back to the first one. – I'm Clueless Aug 10 '20 at 12:48
0

Since SQLite.create is asynchronous, you have to await it for that you also have to make the function getAllLoans async with export const getAllLoans = async (): Loan[] => {

So, you want to do it like so:

let db = await SQLite.create(...);
Mark
  • 485
  • 7
  • 14