skip to Main Content

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

Answers


  1. 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.

    Login or Signup to reply.
  2. 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))
    
    Login or Signup to reply.
  3. 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:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search