0

I am trying to achieve Master-Detail View based on a JSON file. The PHP functions well. It brings the data as it is supposed to be. Config.js, or controller.js are working fine. However, I am getting an error as shown below. The SET property is undefined.

I am a beginner. I thought putting 'this.___ ' would be setting the property. But, it seems that I am missing. If not, what could be wrong? I took the reference from the below link.

Could anyone please tell me what is wrong? Perhaps, how to set the property?

(function () {
    'use strict';
    var app = angular.module('myProject', []);
    app.service('ProjectService', function($http) {
        $http.get("projects_read.php", {})
            .then(function(response){
                var pjts = response.data;
                this.getProjects = function() { //ERROR occurs
                    return pjts;  
                };

                this.getProject = function(id) {
                    for (var i = 0; i < pjts.length; i++) {
                        if (pjts[i].id === id) {
                            return pjts[i];
                        }
                    }
                    return null;
                }

                console.log(pjts);
            });
    })
})();

[ERROR] Cannot set property 'getProjects' of undefined.

[Reference Link] http://plnkr.co/edit/VJxlqguJZGrIutAFLCNc?p=preview

Thank you in advance for your assistance!

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
James D.
  • 117
  • 8

2 Answers2

1

you're setting the property getProjects on the wrong context (this)

The callback function(response){} creates a new context (in strict mode is undefined that's why you get: Cannot set property 'getProjects' of undefined) try saving a reference of the service outside the promise and use that context.

app.service('ProjectService', function($http) {
    var _this = this; //save context of the service
    $http.get("projects_read.php", {})
    .then(function(response){
        var pjts = response.data;

        _this.getProjects = function() {
          return pjts;  
        };

        this.getProject = function(id) {
        for (var i = 0; i < pjts.length; i++) {
            if (pjts[i].id === id) {
            return pjts[i];
            }
        }
        return null;
        }
        console.log(pjts);
    });
  })
Karim
  • 8,454
  • 3
  • 25
  • 33
1

As Karim also points out you can solve it by using "var _this = this"

Another solution is to bind this:

(function () {
    'use strict';
    var app = angular.module('myProject', []);
    app.service('ProjectService', function($http) {
        $http.get("projects_read.php", {})
            .then(function(response){
                var pjts = response.data;
                this.getProjects = function() { //ERROR occurs
                    return pjts;  
                };

                this.getProject = function(id) {
                    for (var i = 0; i < pjts.length; i++) {
                        if (pjts[i].id === id) {
                            return pjts[i];
                        }
                    }
                    return null;
                }

                console.log(pjts);
            }.bind(this));
    })
})();
Mick
  • 837
  • 8
  • 23
  • Thank you for your comment! It also works! I think I need to see more about this kind of function in the future if possible. :) – James D. Oct 26 '17 at 14:04
  • You're welcome :) "This" in javascript and its context can be very confusing, but it's an important concept to grasp. – Mick Oct 27 '17 at 07:05