Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling services return "this is undefined" #321

Closed
ibnumalik opened this issue May 27, 2016 · 4 comments
Closed

Calling services return "this is undefined" #321

ibnumalik opened this issue May 27, 2016 · 4 comments
Labels

Comments

@ibnumalik
Copy link

ibnumalik commented May 27, 2016

Hi,

I have a problem calling my service in this starter kit. Below is my component

class VenuesController {
    constructor($log, FoursquareService) {
        'ngInject';
        this.$log = $log;
        this.FoursquareService = FoursquareService;
    }
    $onInit() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(this.onPositionUpdate);
        }
    }
    onPositionUpdate(position) {
        var lat = position.coords.latitude;
        var lng = position.coords.longitude;
        console.log(lat, lng);
        this.$log.log(lat, lng);
        this.FoursquareService.getVenues(lat, lng).then(this.getVenuesData, this.unableToGetVenuesData);
    }
    getVenuesData(data) {
        console.log(data.venues);
    }
    unableToGetVenuesData(result) {
        console.log(result);        
    }
}
export const SenaraiMasjidComponent = {
    templateUrl: './views/app/components/some-component/venues.component.html',
    controller: VenuesController,
    controllerAs: 'vm',
    bindings: {}
}

In the onPositionUpdate, the this method will get an error of undefined.
I have read through and the possible error is that the this method is nested.
I only get the API call if I do this, but still there is error:

class VenuesController {
    constructor($log, FoursquareService) {
        'ngInject';
        this.$log = $log;
        this.FoursquareService = FoursquareService;
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(onPositionUpdate);
        }
        function onPositionUpdate(position) {
            var lat = position.coords.latitude;
            var lng = position.coords.longitude;
            console.log(lat, lng);
            this.$log.log(lat, lng);
            this.FoursquareService.getVenues(lat, lng).then(this.getVenuesData, this.unableToGetVenuesData);
        }
        function getVenuesData(data) {
            console.log(data.venues);
        }
        function unableToGetVenuesData(result) {
            console.log(result);
        }
    }
    $onInit() {}
}
export const SenaraiMasjidComponent = {
    templateUrl: './views/app/components/some-component/venues.component.html',
    controller: VenuesController,
    controllerAs: 'vm',
    bindings: {}
}

Any ideas how to properly get the services working properly?
And here is my service if it is necessary:

export class FoursquareService {
    constructor($http, $log) {
        'ngInject';
        this.$http = $http;
        this.$log = $log;
        this.butiranKunci = {
            versi: "",
            client_id: "",
            client_secret: "",
            category_id: ""            
        };
    }
    getVenues(lat, lng) {
        var url = "https://api.foursquare.com/v2/venues/search?v=" + this.butiranKunci.versi + 
        "&ll=" + lat + "," + lng + "&intent=browse&radius=10000&categoryId=" + this.butiranKunci.category_id + 
        "&client_id=" + this.butiranKunci.client_id + "&client_secret=" + this.butiranKunci.client_secret;

        return this.$http.get(url).then(function(yes) {
            return yes.data.response;
        });
    }
}
@flick36
Copy link
Contributor

flick36 commented May 27, 2016

You have to use arrow functions since the starter uses ES6 #280 (comment)

try changing your functions to neither variables:

this.onPositionUpdate = (position) => {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    console.log(lat, lng);
    this.$log.log(lat, lng);
    this.FoursquareService.getVenues(lat, lng).then(this.getVenuesData, this.unableToGetVenuesData);
}
this.getVenuesData = (data) => {
    console.log(data.venues);
}
this.unableToGetVenuesData = (result) =>{
    console.log(result);
}

or functions outside the constructor as:

constructor($log, FoursquareService) {
    'ngInject';
    this.$log = $log;
    this.FoursquareService = FoursquareService;
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(onPositionUpdate);
    }
}
onPositionUpdate(position){
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    console.log(lat, lng);
    this.$log.log(lat, lng);
    this.FoursquareService.getVenues(lat, lng).then(this.getVenuesData, this.unableToGetVenuesData);
}
getVenuesData(data){
    console.log(data.venues);
}
unableToGetVenuesData(result){
    console.log(result); = 
}

and instead of var use let preferentially

Also, i think you want to call a function when you call this.getVenuesData, this.unableToGetVenuesData they're functions and they require a param so you should be calling them as: this.getVenuesData(someParam), this.unableToGetVenuesData(someParam)

so your .then function should probably look like this:

this.FoursquareService.getVenues(lat, lng).then(the_param_you_are_returning_in_your_service)=>{
    this.getVenuesData(someParam);
    this.unableToGetVenuesData(someParam)
});

@ibnumalik
Copy link
Author

Hi Flick36, thanks for the reply. I have use the ES6 by defining my functions outside of the constructor as you can see in my first code snippet. Unfortunately, this will cause an error where the this method will be undefined.

My first thought is the code below will call onPositionUpdate function, and pass a position object

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.onPositionUpdate);  // passing onPositionUpdate without this will not work.
    }

then, the function below will take the object and save it respectively. I try ro call service in this function, but they will return undefined error.

onPositionUpdate(position){
    let lat = position.coords.latitude;
    let lng = position.coords.longitude;
    console.log(lat, lng);
    this.$log.log(lat, lng); // will not work as this is undefined
}

image

@flick36
Copy link
Contributor

flick36 commented May 27, 2016

Do as i say: set the function as a variable in your constructor:

like this:

this.onPositionUpdate = (position) => {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    console.log(lat, lng);
    this.$log.log(lat, lng);
    this.FoursquareService.getVenues(lat, lng).then(this.getVenuesData, this.unableToGetVenuesData);
}

@ibnumalik
Copy link
Author

Ok now I understand. I guess I have to start exploring es6 syntax.

Thanks again flick36!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants