0

I am making my first steps on NodeJs. I came from Java world, and my head stuck when writing asynchronous code. I have read a lot about asynchronous flow, when dealing with I/O block operations but i don't really know how to solve this issue.

I am doing a google API call, when i create an instance of "point" object to retrieve longitude and latitude of the point.

In my "app.js" flow, i invoke a function that inside of it call another function that requires that longitude and latitude. As you see, at this point google API call didn't come back and its retrieve "undefined".

How to think this problem in a "Asynchronous way"?

//app.js

const express = require('express');
const POI = require('./models/poi');
var app = express ();

app.get('/', (req, res) => {

    var poiA = new POI(19146, "Saraza", 2, 3);
    var poiB = new POI(19146, "Saraza", 4, 5);


    console.log(poiA.estaAXMetrosDeOtroPoi(poiB, 10));

});

app.listen(3000);

const Point = require('./point');

function POI (direccion, nombre) {

    var self = this;

    var direction = direccion;

    var nombre = nombre;

    var point = new Point(direccion);


    self.getPoint = () => {
        return point;
    };

    self.estaAXMetrosDeOtroPoi = (otroPoi, distancia) => {
        let poiDistance = point.distanceBetweenPOIsCoords(point, otroPoi.getPoint());
        return (distancia >= poiDistance);
    };

}

module.exports = POI;

var geolib = require('geolib');
var geoCode = require('../services/geoCode');

function Point (direccion){

    var self = this;

    self.latitude;
    self.longitude;

    
    
    self.geoLocalizate =  (direccion) => {
        
        //Here i am making google API call
        
        geoCode.geocodeAddress(direccion, (errorMessage, results) => {
            if(errorMessage){
                self.latitude = null;
                self.longitude = null;
            }else{
                self.latitude = results.latitude;
                self.longitude = results.longitude;
            }
        });

    };

    self.geoLocalizate(direccion);

    self.getCoord = () => {
        return {"latitude": self.latitude, "longitude":                                         self.longitude};
    };
    
    //Function throwing error, becouse of latitude, longitude "Undefined"
    
    self.distanceBetweenPOIsCoords = (pointA, pointB) => {
        let coordA = pointA.getCoord();
        let coordB = pointB.getCoord();
        return geolib.getDistance(coordA, coordB);
    };


};

3
  • The way async code is handled in JS is similar to how it is in Java, you pass in a callback and the function will call it once the action is done. Commented May 1, 2017 at 17:45
  • Yes, i understand that but how you could solve my issue? Commented May 1, 2017 at 17:52
  • slideshare.net/NishchitDhanani/async-history-javascript Commented May 3, 2017 at 3:03

1 Answer 1

1

You should be aware that if you call an async function, you have no garantuee that it will finish at some point in your code. That means that

 self.geoLocalizate(direccion);
self.getCoord = () => {
        return {"latitude": self.latitude, "longitude":                                         self.longitude};
    };
...

will be processed before

geoCode.geocodeAddress(direccion, ...

has finished and thats why the values you define in your callback are undefined. The real execution might look like this, e.g.:

var self = this;

self.latitude;
self.longitude;



self.geoLocalizate =  (direccion) => {

    //Here you make the async call, but execution continues...

};

self.geoLocalizate(direccion);

self.getCoord = () => {
    return {"latitude": self.latitude, "longitude":                                         self.longitude}; // undefined, because async has not finished
};

// NOW, async function has finished, and your callback code is executed...
if(errorMessage){
            self.latitude = null;
            self.longitude = null;
        }else{
            self.latitude = results.latitude;
            self.longitude = results.longitude;
        }
//Function throwing error, becouse of latitude, longitude "Undefined"

self.distanceBetweenPOIsCoords = (pointA, pointB) => {
    let coordA = pointA.getCoord();
    let coordB = pointB.getCoord();
    return geolib.getDistance(coordA, coordB);
};

};

also, you cannot return something from an async function call, you have to provide a callback function and pass your return object to it. to garantuee proper execution, you have to wrap all code that required the async function to be completed in your callback, e.g. like this

function Point (direccion, callback){

var self = this;

self.latitude;
self.longitude;

self.geoLocalizate =  (direccion) => {

    //Here i am making google API call

    geoCode.geocodeAddress(direccion, (errorMessage, results) => {
        if(errorMessage){
            self.latitude = null;
            self.longitude = null;
        }else{
            self.latitude = results.latitude;
            self.longitude = results.longitude;
        }

    self.geoLocalizate(direccion);

    self.getCoord = () => {
        return callback(null, {"latitude": self.latitude, "longitude":                                         
        self.longitude});
    };

    self.distanceBetweenPOIsCoords = (pointA, pointB) => {
        let coordA = pointA.getCoord();
        let coordB = pointB.getCoord();
        return callback(null, geolib.getDistance(coordA, coordB));
   };
  });
};
Sign up to request clarification or add additional context in comments.

1 Comment

What should be the callback? I should pass it when i create point instance? (var point = new Point (direccion) )

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.