0

I am not able to update the values within the view of the page using angularJS. These values are supposed to change after having a call to the method done from the website.

The html element holding the value is

<p>Current song playing: {{currentSong.SongName}}</p>

Here is my angular code, with just the parts relevant to my issue

    var myApp = angular.module('myApp', ['ngMaterial', 'ngMessages']);

    myApp.controller('myCtrl', function ($scope, $http, $timeout, $q) {



        $scope.currentSong = {
            SongName: ''
        }



        loadCurrent().then(function (data) {

            $scope.currentSong = { SongName: data };

        });




        $scope.updateSong = function () {
            loadCurrent().then(function (data) {

                $timeout(function () {

                    $scope.currentSong = { SongName: data };


                },200);


            });

        }

        function loadCurrent() {

            var deffered = $q.defer();

            $timeout(function () {

                $http({
                    method: 'GET',
                    port: '8080',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                }).then(function successCallback(response) {


                    deffered.resolve(response.data.SongName);




                }, function errorCallback(response) {
                    console.log(response)
                });

            }, 500);

            return deffered.promise;
        };


    });

The initial load current sets the value on the page, however if I call updateSong the value does not change on the page. However, I do see the value change within the $scope during debugging.

  • I would suggest changing the property itself instead of reassigning the whole `currentSong` object: `$scope.currentSong.SongName = data;`. Btw why do you use those `$timeout`s there? – Martin Adámek Apr 24 '18 at 17:09
  • I just attempted to do that, however it did not work. I am using a $timeout in the updateSong to try to force an $apply. Even if I remove the $timeout it still does not work. – Ion Sirotkin Apr 24 '18 at 17:23

2 Answers2

0

Rather than reassigning $scope.currentSong, you need to modify it:

loadCurrent().then(function(data) {
  $scope.currentSong.SongName = data;
});

$scope.updateSong = function() {
  loadCurrent().then(function(data) {
    $timeout(function() {
      $scope.currentSong.SongName = data;
    }, 200);
  });
}

See related post on scope prototypal / prototypical inheritance in AngularJS .

mikwat
  • 533
  • 3
  • 11
  • @IonSirotkin sorry, I missed a spot, `$scope.updateSong` also needs to be updated. Check my updated answer. – mikwat Apr 24 '18 at 17:31
0

I have tried to replicate the issue and it seems to be working in Fiddle - https://jsfiddle.net/Aks1357/e6yh2n1o/

HTML:

<div ng-controller="MyCtrl">
    <p>Current song playing: {{currentSong.SongName}}</p>
    <p><input type="button" value="Update Song" ng-click="updateSong()" /></p>
</div>

JS:

var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', MyCtrl);

function MyCtrl($scope, $timeout, $q, $http) {
    $scope.currentSong = {
        SongName: ''
    }

    // Aks: Commented - as it works on load
    //loadCurrent().then(function (data) {
        //$scope.currentSong.SongName = data;
    //});

    $scope.updateSong = function () {
        loadCurrent().then(function (data) {
            // Aks: just directly assign new value
            $scope.currentSong.SongName = data;

            // Aks: NOTE - the delay parameter for `$timeout` is missing, the intention is to wait until the end of the `$digest` cycle and then set $scope
            // Aks: Commented - use below three lines if the value is not updated
            //$timeout(function () {
                //$scope.$apply();
            //});
        });
    }

    function loadCurrent() {
        var deffered = $q.defer();
        $timeout(function () {
            // Aks: Commented - to mimick in fiddle
            //$http({
                //method: 'GET',
                //port: '8080',
                //headers: {
                    //'Content-Type': 'application/json'
                //}
            //}).then(function successCallback(response) {
                deffered.resolve('Dummy Song!');
            //}, function errorCallback(response) {
                //console.log(response)
            //});
        }, 500);
        return deffered.promise;
    }
}

Comments inline. Hope this helps!

Aks1357
  • 1,062
  • 1
  • 9
  • 19
  • I found the issue in my code. I broke the code into different controllers with each dealing with their own perspective portion of the site. So this small portion on its own was working, however with all of the other AngularJS code it was not. – Ion Sirotkin Apr 24 '18 at 17:46