1

In my react-native i have a problem with async/await functions. I need to get all users from database and finally return it. but things are not happening in correct order.

I'm confused how should i use async/await.

is this the right usage of it? Any help is highly appreciated

import React, {Component, PropTypes} from 'react';
import {
  ActivityIndicator,
  StyleSheet,
  Text,
  View,
  NetInfo,
  AlertIOS,
} from 'react-native';

var SQLite = require('react-native-sqlite-storage');
var Loading = require("./Loading");
var DeviceInfo = require('react-native-device-info');
import { Actions } from 'react-native-router-flux';
var LOADING = {};
var db = SQLite.openDatabase({name : "oc.db", location: 'default'});
import CodePush from "react-native-code-push";
import I18n from 'react-native-i18n';
import translations from './translations';
I18n.fallbacks = true;

export default class Grab extends Component{
  constructor(props) {
        super(props);
        this.state = {
            terms: '',
            isLoading: false,
            isConnected: null,
            coursesFetched: false,
            registerFetched: false,
        };
    }

  componentWillMount() {

    NetInfo.isConnected.fetch().then(isConnected => {
      this.setState({
        isConnected: isConnected
      });
    });

    NetInfo.isConnected.addEventListener(
      'change',
      isConnected => {
        this.setState({
          isConnected: isConnected
        });
        console.log('Grab: internet status is', this.state.isConnected);
        this.sync();
      }
    );

    this.GrabData();

  }

  toggleAllowRestart() {
    this.state.restartAllowed
      ? CodePush.disallowRestart()
      : CodePush.allowRestart();

    this.setState({ restartAllowed: !this.state.restartAllowed });
  }

  sync() {
    console.log("Grab: Running manual code push update");
  CodePush.sync(
    {
      installMode: CodePush.InstallMode.IMMEDIATE,
      updateDialog: false
    },
  );
}

async getUsers() {
    const tx = await (
        new Promise(resolve =>
            db.transaction(resolve)
        )
    );

    const users = await (
        new Promise((resolve, reject) =>
            tx.executeSql(["SELECT * FROM users"],[], (tx, results) => {
                const userList = results.rows
                        .map((row, index) => ({
                            userId: row.item(index).userId,
                            userName: row.item(index).userName,
                            userMail: row.item(index).userMail,
                            active: row.item(index).active,
                            firstName: row.item(index).firstName,
                            lastName: row.item(index).lastName,
                            accessToken: row.item(index).access_token,
                            host: row.item(index).host,
                        }));

                resolve(userList);
            })
        )
    );
    console.log('users to return:', users);
    return users;
};

  async getBookable(users){
    console.log('Exectuing function getBookable. received data:', users);
    let results = [];
    console.log(users.length, ' Users received');
    for(let n=0; n < users.length; n++){
      try {
        let host = users[n].host;
        let access_token = users[n].access_token;
        let userId = users[n].userId;
        let response = await fetch(host + 'event/my_events', {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'language': DeviceInfo.getDeviceLocale(),
            'Authorization': 'Bearer ' + access_token
          }
        });
        let responseData = await response.json();
        //// Get container details
        if(responseData.container.length > 0){
          for(let i=0; i < responseData.container.length; i++){
            let cnid = responseData.container[i].nid;
            let ctitle = responseData.container[i].title;
            results.push(
              "INSERT INTO containersC (userId, nid, title) VALUES ('" + userId + "','" + cnid + "', '" + ctitle + "')"
            );
            //// Get courses for each container
            for(let j=0; j < responseData.container[i].course.length; j++){
              let course_id = responseData.container[i].course[j].nid;
              let title = responseData.container[i].course[j].title;
              let cost = responseData.container[i].course[j].cost;
              let status = responseData.container[i].course[j].status;
              let period = responseData.container[i].course[j].period.time_sys;
              //// Get details for each course
              try {
                let resp = await fetch(host + 'event/course_detail/' + course_id, {
                  method: 'POST',
                  headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'language': DeviceInfo.getDeviceLocale(),
                    'Authorization': 'Bearer ' + access_token
                  }
                });
                let respData = await resp.json();

                let desc = respData.data.content[0].value;
                let capacity = respData.data.content[1].value;
                let image = respData.data.image;
                let status = respData.data.book;
                let cancel = respData.data.cancel;
                let cd = responseData.data.dates;

                results.push(
                  "INSERT INTO courses (userId, course_id, container_nid, title, cost, status, period, desc, capacity, image, cancel) VALUES ('" + userId + "','" + course_id + "', '" + cnid + "', '" + title + "', '" + cost + "', '" + status + "', '" + period + "', '" + desc + "', '" + capacity + "', '" + image + "', '" + cancel + "')"
                );

                //// Getting lecture dates for each course
                for(let a=0; a < cd.length; a++){
                  let sdate = cd[a].start_time.split(" ");
                  let edate = cd[a].end_time.split(" ");
                  results.push(
                    "INSERT INTO lectures (userId, course_id, title, start_time, end_time, start_date, end_date, room, teacher) VALUES ('" + userId + "','" + course_id + "', '" + cd[a].title + "', '" + sdate[1] + "', '" + edate[1] + "', '" + sdate[0] + "', '" + edate[0] + "', '" + cd[a].room + "', '" + cd[a].teacher + "')"
                  );
                }
                //// End getting lecture dates for courses
                return true;
              } catch(error) {
                console.error(error);
              }
              //// End getting details for courses
            }
            //// End getting courses for containers
          }
        }
        //// End getting container details
        return true;
      } catch(error) {
        console.error(error);
      }
    }
  }

  redirectUser(){
    Actions.tabbar({type: 'reset'});
  }

  async runQuery(query) {
    await db.transaction(tx => {
      return Promise.all(query.map(async (q) => {
        try {
          let results = await tx.executeSql(q, []);
          console.log('Query', q, 'Executed. results:', results);
        } catch(err) {
          console.log('Something went wrong while executing query', q, 'error is', err);
        }
      }));
    });
    return true;

  }

  async GrabData(){
    try {
      let users = await this.getUsers();
      //let [courses, register, evaluation] = await Promise.all([getBookable(users), getRegister(users), getEvaluation(users)]);
      let courses = await this.getBookable(users);
      //let query = [courses, register, evaluation];
      let query = [courses];
      await this.runQuery(["DELETE FROM containersC", "DELETE FROM courses", "DELETE FROM lectures", "DELETE FROM containersR", "DELETE FROM register", "DELETE FROM lectures", "DELETE FROM evaluations", "DELETE FROM fields"]);
      await this.runQuery(query);
      //this.redirectUser();
    } catch(error){
      console.log(error);
    }
  }


  render() {

return(
    <View style={styles.container}><Loading/></View>
  );
  }

}

var styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: "#fff",
      flexDirection: "column",
    },
});

Grab = CodePush(Grab);

Using SQLite for React-Native : https://github.com/andpor/react-native-sqlite-storage

4
  • 2
    i have a problem with async/await functions - what is the problem? Commented Oct 11, 2016 at 11:10
  • @JaromandaX i can't get it working. simply it doesn't work. i need to get all users from database, and then return it. Commented Oct 11, 2016 at 11:12
  • @JaromandaX Not if it's a method in the middle of a class. Commented Oct 11, 2016 at 11:15
  • @JaromandaX when i'm putting function it gives syntax error. async function getUsers() Commented Oct 11, 2016 at 11:16

1 Answer 1

1

I would go with a "multi step approach" by wrapping the callback-based calls into promises in order to use the advantages of a synchronous call sequence in the main part of the async function and instead of using the loop I would go with mapping the rows to the desired data structure.

async getUsers() {
    const tx = await (
        new Promise(resolve =>
            db.transaction(resolve)
        )
    );

    const users = await (
        new Promise((resolve, reject) =>
            tx.executeSql(["SELECT * FROM users"], [], (tx, results) => {
                const item = results.rows.item;
                const count = item.length;

                const userList = Array.apply(null, Array(count))
                    .map((dummy, index) => {
                        const user = item(index);

                        return {
                            userId: user.userId,
                            userName: user.userName,
                            userMail: user.userMail,
                            active: user.active,
                            firstName: user.firstName,
                            lastName: user.lastName,
                            accessToken: user.access_token,
                            host: user.host,
                        };
                    });

                resolve(userList);
            })
        )
    );

    return users;
};
Sign up to request clarification or add additional context in comments.

13 Comments

thanks for your answer. i have simply copy & paste it, but it gives syntax error in the line you have used .reduce , what could it be?
Autsch. Was a missing ) before the reduce
may i ask you to update the answer? i tried adding it, still same issue.
I updated the answer and also get rid of the object data structure. Instead the userList is now an array with user objects.
Thanks. should i use async function getUsers or async getUsers? when i use function it gives syntax error
|

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.