Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: How should I update a property on a resolved promise inside of my watch listener?

Consider this Plunkr.

Inside of my watch listener, I'd like to update a property on a resolved promise.

  • Is it correct to modify values on the $$v property?
  • If not, then what should I do?

Here is the HTML:

<!DOCTYPE html>
<html id="ng-app" ng-app="myAngularApp">

  <head>
    <script data-require="angular.js@*" data-semver="1.2.0-rc2" src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="MyController">
    <input ng-model="myDto.Weight" />{{myDto.Status}}
  </body>

</html>

Here is the JavaScript:

var myDto = {Weight: 200, Status: 'Acceptable'};

var myAngularApp = angular.module('myAngularApp', []);

myAngularApp.factory('myService', function($q){
  return {
    getMyDto: function(){
      var deferred = $q.defer();
      deferred.resolve(myDto);
      return deferred.promise;
    }
  };
});

myAngularApp.controller('MyController', function MyController($scope, myService){
  $scope.myDto = myService.getMyDto();
  $scope.$watch('myDto.Weight', function(newVal, oldVal){
    if (newVal < 150) {
      $scope.myDto.$$v.Status = 'Too Light!'; // Is this the recommended way of doing it?
    }
    else if (500 < newVal) {
      $scope.myDto.$$v.Status = 'Too Heavy!';
    }
    else if (Number(newVal)) {
      $scope.myDto.$$v.Status = 'Acceptable';
    }
    else {
      $scope.myDto.$$v.Status = 'Not a number!';
    }
  });
});
like image 938
Jim G. Avatar asked Sep 07 '13 21:09

Jim G.


People also ask

Which of these runs everytime to check if there are updates to any of the variables registered with AngularJS?

At key points in your application AngularJS calls the $scope. $digest() function. This function iterates through all watches and checks if any of the watched variables have changed.

What is the use of $Watch in AngularJS?

$watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in Angularjs to handle variable changes in application.

What is Q defer () in AngularJS?

Simply put you can use $q. defer() to create a Promise. A Promise is a function that returns a single value or error in the future. So whenever you have some asynchronous process that should return a value or an error, you can use $q. defer() to create a new Promise.

How do I upgrade AngularJS version?

Updating dependencies 6, change the versions of angular , angular-animate and angular-resource packages to 1.6. 6 in the dependencies section of the package. json file. Run npm install to ensure that the specified dependencies are downloaded into the application.

How to make HTTP GET request using ES6 promise in angular?

Open your Angular project in your favorite code editor and then go to app.module.ts file and import HttpClientModule service. Then also register it inside the imports array. Next, go to app.component.ts file. Here we will write the core logic to make the HTTP GET request and manage the response using the ES6 Promise in Angular.

How to manage HTTP response asynchronously in angular 11 promises?

Angular 11 Promises Example with HttpClient API. In this section, we are going to look at how to use Promises in Angular to manage the HTTP response asynchronously. Open your Angular project in your favorite code editor and then go to app.module.ts file and import HttpClientModule service. Then also register it inside the imports array.

What are AngularJS promises?

AngularJS promises are an extremely powerful tool. They allow you to make a multi-layered and complex system based on asynchronous functions, with error and in-progress notification handling, all without getting into callback hell. This post attempts to explain both creating and using AngularJS promises.

Is AngularJS listening to the correct events?

Now AngularJS is listening to the correct events to detect errors, i.e. even empty responses can be successful. If you expected $resource to strip these types of properties before, you will have to manually do this yourself now.


2 Answers

I wouldn't modify $$v directly, it's an implementation detail. Instead, use then to get the result of the promise, then use it however you like. That requires minimal change to your code.

Demo link

myAngularApp.controller('MyController', function MyController($scope, myService){
  ($scope.myDto = myService.getMyDto()).then(function(myDto) {
    $scope.$watch('myDto.Weight', function(newVal, oldVal){
      if (newVal < 150) {
        myDto.Status = 'Too Light!'; // Is this the recommended way of doing it?
      }
      else if (500 < newVal) {
        myDto.Status = 'Too Heavy!';
      }
      else if (Number(newVal)) {
        myDto.Status = 'Acceptable';
      }
      else {
        myDto.Status = 'Not a number!';
      }
    });
  });
});
like image 69
Buu Nguyen Avatar answered Sep 22 '22 16:09

Buu Nguyen


It is a little bit weird to modify the promise since a promise represents the result of an action that is performed asynchronously. It is self-contained.

I think it is better to add another service function to update data the status. Try this

myAngularApp.factory('myService', function ($q) {
    var deferred = $q.defer();
    return {
        getMyDto: function () {
            deferred.resolve(myDto);
            return deferred.promise;
        },
        updateStatus: function (status) {
            myDto.Status = status;
            deferred.resolve(myDto);
            return deferred.promise;
        }
    };
});

myAngularApp.controller('MyController', function MyController($scope, myService) {
    $scope.myDto = myService.getMyDto();
    $scope.$watch('myDto.Weight', function (newVal, oldVal) {
        if (newVal < 150) {
            myService.updateStatus('Too Light!');
        } else if (500 < newVal) {
            myService.updateStatus('Too Heavy!');
        } else if (Number(newVal)) {
            myService.updateStatus('Acceptable');
        } else {
            myService.updateStatus('Not a number!');
        }
    });
});

Updated Plunker

like image 37
zs2020 Avatar answered Sep 18 '22 16:09

zs2020