I'm new to OOP. My knowledge of promises/asynchronously/synchronously running functions is simply basic. I'd really appreciate your time and attention!
This is the example from React-Native docs:
async function getMoviesFromApi() {
try {
let response = await fetch('https://facebook.github.io/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch(error) {
console.error(error);
}
}
As i understand from code above, getMoviesFromApi is declared as async function. which means it will execute functions one after other. Right? please correct me if not!
it will first wait for fetch to finish then call response.json, right?
I have few functions, which get data from a server via fetch, then insert them to sqlite database. so they don't return anything.
in example above, fetch returns something. but my functions, not. so, can i use this structure to make javascript run my functions consequently? what is the best practice / right solution to achieve this?
let query = [];
export default class Main extends Component(){
constructor(props){
super(props);
}
componentWillMount(){
this.getBookable();
this.getBooked();
this.runQuery();
this.redirectUser();
//// i need this functions to run consequently. not all in same time, one after eachother
}
getBookable(){
let fetchedData = fetch(); /// Fetchs data from remote server
query.push('INSERT INTO bookable (data) VALUES (' + fetchedData + ')');
}
getBooked(){
let fetchedData = fetch(); /// Fetchs data from remote server
query.push('INSERT INTO booked (data) VALUES (' + fetchedData + ')');
}
runQuery(){
for(let i=0; i < query.length; i++){
db.transaction((tx) => {
tx.executeSql(query[i],[], (tx, results) => {
console.log('Query', query[f], 'Executed. results:', results);
}, (err)=>{
console.log('Something went wrong while executing query',query[i],'error is', err);
});
});
}
}
redirectUser(){
Actions.tabbar({type: 'reset'});
//// Using redux. redirect user to another page
}
}
First, i get bookable courses, then booked courses, insert them to database, then redirect user to another page via redux
How should i update my code?
UPDATE :
updated code according to @Bergi :
is this the right way?
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(){
let userlist = [];
let query = [SELECT * FROM users];
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);
for(let ind = 0; ind < len; ind++ ){
userlist[ind] = {
userId: results.rows.item(ind).userId,
userName: results.rows.item(ind).userName,
userMail: results.rows.item(ind).userMail,
active: results.rows.item(ind).active,
firstName: results.rows.item(ind).firstName,
lastName: results.rows.item(ind).lastName,
accessToken: results.rows.item(ind).access_token,
host: results.rows.item(ind).host,
};
}
} catch(err) {
console.log('Something went wrong while executing query', q, 'error is', err);
}
}));
});
return userlist;
}
async getBookable(users){
let results = [];
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 function GrabData(){
try {
let users = await getUsers();
//let [courses, register, evaluation] = await Promise.all([getCourses(users), getRegister(users), getEvaluation(users)]);
let [courses] = await Promise.all([getCourses(users)]);
//let query = [courses, register, evaluation];
let query = [courses];
await 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 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);
I'm using react-native-sqlite-storage :
https://github.com/andpor/react-native-sqlite-storage