2

Hello I'm having a problem that haven't searched before

I'm trying to recode my javascript used for accessing google api's so that I can create objects to access them in further projects . Let me Explain the Code because I'm not posting the original code here below code is the just like an example of my code

I'm a having constructor function and it has arrays declared with 'this' keyword. and Then I have an prototype of the constructor function and inside that prototype I had a nameless function created to access jquery requested output from a server.But I'm unable to access those array objects

function cons(){
	this.objectarray = [];
}
cons.prototype.profun = function(){
	this.objectarray[0] = 'working';
	alert(this.objectarray[0]);//Access is possible
	$.get('requesting url',{'parameters'},function(data){
		alert(this.objectarray[0]);//Access is not possible
	});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

when I try to access the object inside that jquery function I'm getting this error from browser console

TypeError: this.YouTubeTitle is undefined

4
  • Possible duplicate of How do JavaScript closures work? Commented May 29, 2017 at 18:55
  • If you want to use this within the callback function, you had better bind that callback to this (see @Björn's closures link for alternatives) Commented May 29, 2017 at 18:58
  • The this floats to whomever invokes the callback function. So you might also try binding the callback function like function(data){alert(this.objectarray[0]);}.bind(this) Commented May 29, 2017 at 22:11
  • I doesn't know if linked closures have solution or not but this function(data){alert(this.objectarray[0]);}.bind(this) worked thank you @Redu for the solution Commented May 30, 2017 at 3:23

4 Answers 4

2

You have to cache the this object so that when you use the this keyword in your callback, it refers to the correct object:

function cons(){
	this.objectarray = [];
}
cons.prototype.profun = function(){
  // this is volatile in JavaScript. It's meaning changes depending
  // on the invocation context of the code that contains it. Here,
  // this will refer to your "cons" object instance.
  var self = this;

	this.objectarray[0] = 'working';
	alert(this.objectarray[0]);
	$.get('requesting url','parameters',function(data){
    // But here, "this" will be bound to the AJAX object
		alert(self.objectarray[0]);  // <-- Use cached this object
	});
};

//*************************

var c = new cons();
c.profun();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

6 Comments

@DevelopersWork The code snippet here certainly is working.
sorry @scott it's working I forgot to declare the self variable thanks for the answer
@DevelopersWork if it is working you should accept this answer as the solution to your question :-)
@Björn I accepted the solution but creating another variable can take more memory but rather I use bind option to bind this to the callback
@Björn An object variable takes roughly 2 bytes of memory, which is absolutely nothing. bind returns a new function that also must be stored and will take more than 2 bytes to store. Both solutions will have zero actual impact on performance, but bind is more involved for no real benefit.
|
1

Inside the GET-Callback there is a local this which overrides your Prototype-Function's this. Store the outer this in a named variable and call that inside the callback and you will be fine.

let outerThis = this;
somethingWithCallback(function(){
  alert(outerThis);
})

1 Comment

this is also going to be working but rather than declaring another variable its better to bind the this
1

I've found solution for this from one of the comments

the below code is the solution

function cons(){
	this.objectarray = [];
}
cons.prototype.profun = function(){
	this.objectarray[0] = 'working';
	alert(this.objectarray[0]);
	$.get('requesting url',{'parameters'},function(data){
		alert(this.objectarray[0]);
	}.bind(this));//by binding 'this' we can access the 'objectarray'
}

Thanks for the solution @Redu from comments

Comments

0

You can wrap your anonymous function with $.proxy to persist the outer this context.

function cons() {
  this.objectarray = [];
}
cons.prototype.profun = function() {
  this.objectarray[0] = 'working';
  alert(this.objectarray[0]);
  $.get('requesting url', {
    'parameters'
  }, $.proxy(function(data) {
    alert(this.objectarray[0]);
  }, this));
}

Comments

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.