0

I have a Game class with the properties id, player1 and player2. I want to write a method to fetch data from a mySql database and set the object properties accordingly.

The Object get initialized in an other file called index.js.

My Problem is, that the query isn't finished executing before I call the saveData(data) Method. How can I resolve this problem? Is there a better way to achieve this behaviour?

Game.js:


const db = require('../mySqlConnection');

class Game{
   constructor(){
        this.id = null;
        this.player1 = null;
        this.player2 = null;
   }

    saveData(data) {
        this.id = data.id;
        this.player1 = data.player1;
        this.player2 = data.player2;
    }

    fetchGame(id){

        const q = "SELECT * FROM `games` WHERE `id`= `id`"
        
        db.query(q, (err, data)=\>{
            if(err) return conssole.log(err)
        
            this.saveData(data)
        })

    }

}

module.exports = Game

index.js:

const Game = require('./components/game')

var firstGame = new Game()
firstGame.fetchGame(1)
console.log("index.js: " +JSON.stringify(firstGame))

Output of console.log(): index.js: {"id":null,"player1":null,"player2":null}

Expected output of console.log(): index.js: {"id":"1","player1":"name1","player2":"name2"}

EDIT: I implemented the feature with promises and async/await as seen in another question: How to manipulate object properties in a promise without returning any data?

3 Answers3

0

In your query

const q = "SELECT * FROM `games` WHERE `id`= `id`"

I don't think that id will be replaced with the id passed into the function. You need to replace this with

const q = `SELECT * FROM games WHERE id = ${id}`;

Also, I would recommend adding console.log here:

db.query(q, (err, data)=\>{
  if(err) return conssole.log(err)
  console.log(data);  
  this.saveData(data)
})

This will help to identify the structure of data as expected and filled in with data.

Let me know if this helps.

RAllen
  • 1,235
  • 1
  • 7
  • 10
0

This is a problem of async fetch. Design your fetchGame method like this :

    fetchGame(id, callback){

        const q = "SELECT * FROM `games` WHERE `id`= `id`"
        
        db.query(q, (err, data)=\>{
            if(err) return conssole.log(err)
        
            this.saveData(data)
            callback(data)
        })

    }

Invoke the function like this:

const Game = require('./components/game')

var firstGame = new Game()
firstGame.fetchGame(1, ()=>{
   console.log("index.js: " +JSON.stringify(firstGame))
})

or use async await:

    async fetchGame(id){
        try{

            const q = "SELECT * FROM `games` WHERE `id`= `id`"
        
            const data = await db.query(q)
        
            this.saveData(data)

        }catch(e){
          console.log(e)
        }
    }

Invoke the function like this:

const Game = require('./components/game')

var firstGame = new Game()
await firstGame.fetchGame(1)
console.log("index.js: " +JSON.stringify(firstGame))
Sanket
  • 344
  • 2
  • 6
0

I am not very experienced with the subject, but I do have some interest in this for different reasons.

Based on your question and my little knowledge, I believe that this could be solved with a JS promise.

Maybe something like this (the syntax may be wrong or incomplete, but may serve as a light in the tunnel - I think).

let fetchGame(id) = new Promise((resolve, reject) => {
  const q = "SELECT * FROM `games` WHERE `id`= `id`"
        
  db.query(q, (err, data) => {
    if (err) return reject(console.log(err);
        
    resolve(this.saveData(data));
  });
});

There are a lot of examples in the sites below:

Tyler2P
  • 2,324
  • 26
  • 22
  • 31