0

I am trying to use a variable x defined inside a function P whose value I am trying to set in another function. It always comes undefined.

I tried applying my mind to use closure but it's just going off my head. It does not gives me a string rather a object.

The logic is as follows.

function P(i){
var x;
if(i!=null){    
//this pulls the data correctly and i could see it in network tab response. 
var dataFromQuery=widgets.DATA.create({
    url:"abc/cde",
    queryTemplate :"/query"+i+ "?"
});
    //we query the data and set the value as per the logic.
     dataFromQuery.query(function(data){
         if(data[0].name){
             x=data[0].name; // this stays undefined , and i understand this is a new local variable x.Also the value is here and comes fine here so no issues with the data but i want to set it to the variable defined outside as x.
         }
     })
}
else{
    x="somehardcode";
}

};

I have tried storing the result dataFromQuery.query(function(data){ to a var and then setting it to x but it again comes as a object, which i need as a string. Thanks

NeverGiveUp161
  • 824
  • 12
  • 33
  • dataFromQuery.query is probably a AJAX asynchronous request. 'x' won't be defined until after the request is resolved. If you are trying to access 'x' before it is resolved, it will be undefined. – Hoyen Oct 27 '16 at 18:04
  • Actually i tried printing the value of x in console.log which prints the value which i need. but outside that block say below else i want to see it there it shows undefined.So that means its not the async issue? – NeverGiveUp161 Oct 27 '16 at 18:06
  • 1
    Also the scope of 'x' is only visible within this function P. – Hoyen Oct 27 '16 at 18:06
  • yeah, i need it just in that function. So using this value i will call a another function. – NeverGiveUp161 Oct 27 '16 at 18:06
  • 1
    it is async issue. console.log after the if else statement will happen before the AJAX request resolves. – Hoyen Oct 27 '16 at 18:08
  • Where exactly the value is undefined. Have you tried putting console.log just after assigning value to x ? – Nandan Bhat Oct 27 '16 at 18:09
  • inside the block if i console.log dataFromQuery.query(function(data){ it gives me the value i want,but as soon as i come out of that if else or any other place the value just shows me undefined.So the value what is getting set in that block stays there.I want to use it outside dataFromQuery – NeverGiveUp161 Oct 27 '16 at 18:11
  • Still not able to understand why it is async issue.The value prints after that it goes down. and not sure if its really duplicate the other one is more about asynchronicity – NeverGiveUp161 Oct 27 '16 at 18:20
  • @NeverGiveUp161 I'm certain that the `.query(…)` call *is* asynchronous. It should be stated in the documentation. And you'll notice that the code outside the callback function runs before the log in the callback function, right? – Bergi Oct 27 '16 at 18:22
  • let me check by using async: false if thats really the issue. – NeverGiveUp161 Oct 27 '16 at 18:23
  • that is the issue :( i got confused while reading about closures – NeverGiveUp161 Oct 27 '16 at 18:48
  • @bergi :now i should be refactoring this code to handle the async behavior properly. Still not sure about the hoisting explanation which confused me and i kept thinking that x is a new variable inside the dataFromQuery.query(function(data){ http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/ – NeverGiveUp161 Oct 28 '16 at 09:19
  • Your closure was fine. You *did* assign to the `x` you thought, you just did it at the wrong time. – Bergi Oct 28 '16 at 09:21
  • @Bergi : Is it even possible to implement a solution like this http://stackoverflow.com/questions/2611980/return-value-from-nested-function-in-javascript Because in my case from inside the function P i need to call one more function where i will be sending a value of x set in that if or else block and the function P will execute on its on, no function is dependent on P result. – NeverGiveUp161 Oct 28 '16 at 10:41
  • @NeverGiveUp161 Yes, [something like this](http://stackoverflow.com/a/2612085/1048572) will work. Just call another function from inside the callback where you have the value. And also call that function from the `else` block with the `x` value. – Bergi Oct 28 '16 at 11:32
  • @NeverGiveUp161: The code that uses the variable can not be in the `P` function. The `P` function has to exit before the result from the asynchronous call can be handled. The callback for the query will simply never run before you leave the `P` function. Either place the code inside the callback for the query, or in a separate function that you call from the callback. – Guffa Oct 29 '16 at 15:09
  • @Guffa: Thanks .But i used the old approach of making the ajax call with async : false attribute, because the refactoring it that way won't help my other logic execute properly. – NeverGiveUp161 Nov 02 '16 at 12:50

1 Answers1

-1

I think you're looking for something like this:

var P = (function() {
    var x;
    function _P(i) {
        //your internal logic here
    }
    return _P;
})();

Both xand _P are wrapped in the enclosure and scoped only to the auto-executed anonymous function. _P is returned and available as var P in the outer scope, but x will remain hidden.

RamenChef
  • 5,557
  • 11
  • 31
  • 43
  • i want to call P from different places.And once it enters P the value of X i will use and call another function to calculate something.And am unable to get how your solution will help. – NeverGiveUp161 Oct 27 '16 at 18:14
  • This does alter the scope of `x`, yes, but that doesn't really solve the actual problem. – Bergi Oct 27 '16 at 18:21