BoqBoq
BoqBoq

Reputation: 4704

Javascript Class - Cannot set a property

I have the below code to create a class in javascript.... Now i will only pass the ID of the 'website' and then via an ajax call i will get the rest of the information from the database (JSON ENCODED).

Now my only problem is that when i see whats in the object at the end its only showing the id.

The ajax calls works fine because if i alert this.address after success (ajax) its displaying the result.

What I presume is that I cannot set a property with an ajax request... Can you help?

function website(id) {
     this.id = id; //id


     $.ajax({  //website_information
      type: "GET",
      url: '/proc.php?proc=website_name&id=' + this.id + '',
      success: function(data){
      var tmp = $.parseJSON(data);
     this.address = tmp.website_address;

     this.name = tmp.website_name;
      }
    });

    }

    var obj = new website('20');
    obj.alertwebsite();
    console.log(obj);

Upvotes: 0

Views: 443

Answers (3)

lonesomeday
lonesomeday

Reputation: 237817

There are two problems here. The first is that $.ajax is asynchronous. That means it returns before the request is complete. The success function is run when the request is complete, but obj.alertwebsite() will be run before.

The second problem is the value of this within an AJAX callback. Within the callback, this is set to an object containing all the settings for the AJAX call. This means you are setting address and name properties on this object. There are two ways around this. The first is that = this as in other answers. The nicer way is to use the context setting in the AJAX call:

function website(id) {
    this.id = id; //id

    $.ajax({ //website_information
        type: "GET",
        url: '/proc.php?proc=website_name&id=' + this.id + '',
        context: this,
        success: function (data) {
            var tmp = $.parseJSON(data);
            this.address = tmp.website_address;

            this.name = tmp.website_name;
        }
    });
}

This allows you to customise what this means inside the callback. This is documented in the jQuery AJAX documentation.

Upvotes: 5

Joseph
Joseph

Reputation: 119827

the this inside the AJAX callback may not be referring to the "object-to-be" that your constructor is making. Instead, we preserve the this from the outside by putting it in another variable, like say that. Then we use that to refer to our object-to-be in the AJAX callback.

function website(id) {
    var that = this; //preserve "this"
    this.id = id;
    $.ajax({
        type: "GET",
        url: '/proc.php?proc=website_name&id=' + this.id + '',
        success: function(data){
            var tmp = $.parseJSON(data);
            that.address = tmp.website_address;  //using "that"
            that.name = tmp.website_name;        //using "that"
       }
    });
}

also, you are calling blindly in your obj.alertwebsite() because you don't know if your website info (that.address and that.name) has been loaded or not.

Upvotes: 2

Gavriel
Gavriel

Reputation: 19237

function website(id) {
    // you need to save "this"
    var self = this;
     this.id = id; //id


     $.ajax({  //website_information
      type: "GET",
      url: '/proc.php?proc=website_name&id=' + this.id + '',
      //async: false, // optionally, if you want to get it back syncronously, so the console.log after the function call will already have the data
      success: function(data){
      var tmp = $.parseJSON(data);
     // you need to use the saved "this"
     self.address = tmp.website_address;

     self.name = tmp.website_name;
      }
    });
}

Upvotes: 1

Related Questions