0

I have an issue with a variable which is not being updated in the callback function of a promise as in the block of code below:

 $scope.showSelected= function (node){
                var promise = $http.get("http://127.0.0.1:5000/getResource?ldpr="+node.iri);
                promise.then(function(result){
                    node = result.data;
                });
        };

$scope.showSelected is a callback used by a widget. It has a parameter node which I am trying to update within the callback of the promise. How can I update this variable within callback of the promise

Noor
  • 19,638
  • 38
  • 136
  • 254
  • What is expected result of calling `$scope.showSelected` function? Is `node` defined outside of `$scope.showSelected` function? – guest271314 Jul 16 '17 at 20:54
  • the aim of calling `$scope.showSelected` is only to change the variable `node`. In fact, `$scope.showSelected` is a callback of another widget – Noor Jul 16 '17 at 20:55
  • Is `node` defined before `$scope.showSelected` is called? What do you mean by "callback of another widget"? No value is currently `return`ed from `$scope.showSelected()` call, see [Why is value undefined at .then() chained to Promise?](https://stackoverflow.com/questions/44439596/why-is-value-undefined-at-then-chained-to-promise) – guest271314 Jul 16 '17 at 20:56
  • No value should be returned from `$scope.showSelected(node)`, in fact, I am using a tree widget and the on selecting a node in that tree, `$scope.showSelected(node)` is called with the selected node as a parameter. Based on the node selected, a behaviour can be performed or the content of the node itself can be changed like fetching its children from a server – Noor Jul 16 '17 at 20:59
  • It is not possible to get synchronous results from an asynchronous function call. The closest we are currently able to achieve is using `async/await` to assign a variable identifier to an asynchronous call which will have value of result of call at next line – guest271314 Jul 16 '17 at 21:05
  • Yes, I understand, but I was thinking if this is a `digest` issue in Angular – Noor Jul 16 '17 at 21:07
  • Have little experience with Angular. The code at Question has two issues 1) what `node` is as a variable before, as a parameter, and within scope of function call; and 2) no value is returned from asynchronous function call; thus it is not possible to determine when the function call has completed – guest271314 Jul 16 '17 at 21:09

1 Answers1

1

No value is returned from $scope.showSelected function. return a value from the asynchronous function call, use .then() to perform a task when the asynchronous call which returns a Promise completes

 $scope.showSelected = function (node){
                         return $http.get("http://127.0.0.1:5000/getResource?ldpr="+node.iri);
                       };

 $scope.showSelected(node)
 .then(function(result) {
   // do stuff with `result` : `node`
 })
 .catch(function(err) { // handle error
   console.log(err)
 })
guest271314
  • 1
  • 15
  • 104
  • 177
  • With your answer, I am getting an error `ReferenceError: node is not defined` due to `$scope.showSelected(node)`. By the way, the is the library I am using https://github.com/wix/angular-tree-control – Noor Jul 16 '17 at 21:06
  • If your requirement is to assign result of asynchronous call to `node` you can use `node = result` at `.then()` – guest271314 Jul 16 '17 at 21:06
  • your code, the way you posted the isn't working, without me adding more code – Noor Jul 16 '17 at 21:09
  • How is `$scope.shoeSelected` called and used in your actual code? – guest271314 Jul 16 '17 at 21:10
  • $scope.showSelected is called by the widget when the a node is selected in the tree – Noor Jul 16 '17 at 21:11
  • What is expected result of function call? – guest271314 Jul 16 '17 at 21:11
  • the function call does not need to return any value, it's just a handler for the selected node – Noor Jul 16 '17 at 21:12
  • What do you mean by "handler"? What do you expect to occur when the call is completed? – guest271314 Jul 16 '17 at 21:13
  • node is an object with attributes, in the handler for example, the attributes of node may be changed – Noor Jul 16 '17 at 21:14
  • Yes, though you are expecting to be notified when the asynchronous call has completed and the attributes of `node` have been changed or not, yes? Is `node` a global variable? Are you expecting `node` to be immediately updated in other code when you call `$scope.showSelected`? – guest271314 Jul 16 '17 at 21:15
  • not even if I change it within the promise, it doesn't change – Noor Jul 16 '17 at 21:16
  • Because you have defined `node` as a local variable within `$scope.showSelected` by setting the expected parameter as `(node)`. Try defining the expected parameter as another name, for example `(_node)`, then assigning `node = result.data;`, though you will still need to wait until the `Promise` is resolved before accessing the defined variable, unless Angular is somehow observing changes to `node` global variable – guest271314 Jul 16 '17 at 21:18
  • For example `Promise.resolve(1) .then(function(node) { node = node; console.log(node) // 1 }); console.log(node); setTimeout(function() { console.log(node) // undefined }, 1000)` – guest271314 Jul 16 '17 at 21:22
  • I know that there is something in angular that can force update of variable – Noor Jul 16 '17 at 21:24
  • You can update the value of the global variable at `.then()`. Perform necessary tasks within function passed to `.then()`. Change parameter identifier passed to `$scope.showSelected` `Promise.resolve(1) .then(function(_node) { // note the leading underscore node = _node; console.log(node) // 1 }); console.log(node); // possibly 1 though could be undefined setTimeout(function() { console.log(node) // 1 }, 1000)` – guest271314 Jul 16 '17 at 21:25