'$scope value not updating in view when $scope value is changed in controller

I have a function which uses papaparse.js to immediately get the content of a .csv file selected via a file input as a JSON object list, I then pass this list to a $scope which I console.log.

This is triggered on a button click and works, the issue is the view can't immediately see this $scope has been updated until another action happens, such as clicking the button again, or clicking another button which calls an empty $scope function.

HTML View:

<div ng-controller="myController">        

    <input id="csvfile" type="file" accept=".csv">

    <button type="button" ng-click="readDataList()">
        Preview Data                
    </button>

    {{dataList}}

</div>

And the .js is

var App = angular.module('App', ["ui.bootstrap"]);

App.controller('myController', function ($scope, $http) {   

    $scope.dataList;

    $scope.readDataList = function ()
    {
        var myfile = $("#csvfile")[0].files[0];
        var json = Papa.parse(myfile,
            {
                header: true,
                skipEmptyLines: true,
                complete: function (results)
                {
                    $scope.dataList = results.data;
                    console.log($scope.dataList);
                }
            });        
    };     

});

The list is in the console as soon as the button is clicked, but won't appear in the view unless I clikc the button again.

If I add into the contoller the following:

$scope.testScope = 'hello';

$scope.changeScope = function () {
    $scope.testScope = 'goodbye';
}  

and in the view have the new $scope displayed and the function on a new ng-click this works immediately displaying the new value as soon as the button is clicked. But it doesn't work for the data from the csv even though it appears in console.



Solution 1:[1]

Try $scope.$apply(); after the line $scope.dataList = results.data;

Your Papa.parse function is out of the scope of angular, due to which any changes done in its callback are not captured by angular. So you have to manually trigger the new digest cycle with $scope.$apply() function so that angular checks if anything has changed in its scope and updates the view.

Read this for more detailed information http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Solution 2:[2]

I could able to resolve the issue by using $rootScope, I have used $rootScope and the value is automatically updating the view (HTML template).

Controller:

$rootScope.myVariable = 'update label'

Now, if you update the value of myVariable via any click/change events the updated value will be updated in the HTML template.

HTML file:

<h3>{{myVariable}}</h3>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nandita Sharma
Solution 2 Pradeep Yenkuwale