Search code examples
javascriptangularjsroutesangular-ui-routerangularjs-routing

AngularJS service is not updating the view


I have a service declared in my application.js file within my AngularJS project. It looks like this:

application.factory('interfaceService', function ($rootScope, $timeout) {
    var interfaceService = {};
    interfaceService.lang = "";
    interfaceService.dev = ""
    interfaceService.theme = "";
    interfaceService.integ = "";
    //For Integration Type
    interfaceService.demo = function (dev, theme, integ, lang) {
        this.dev = dev;
        this.theme = theme;
        this.integ= integ;
        this.lang = lang;
        this.broadcastItem();
    };
    interfaceService.broadcastItem = function () {
        $timeout(function(){
             $rootScope.$broadcast('handleBroadcast');
        });
    };
    return interfaceService;
});

I am using the above service to pass variables between 2 of my Controllers. The controller which calls the service is here:

        $scope.buildDemo = function () {
            interfaceService.demo(device, template, integ, language);
            $rootScope.template = template;
            $rootScope.themeFolder = template;
            $state.go("MainPage", {
               "themeName": $rootScope.themeFolder
            });
        }

That function is triggered when the user clicks on a div on my view

<div id='build-btn' ng-click='buildDemo()'>Go</div>

The problem I am having is that my view is not updating when I click on the button. I have to click on it a second time to see any changes. Would anyone know what is causing this? The URL updates and the new view comes onto the page but the elements that should be showing based on the parameters set in the service are not visible until I click on the "Go" button a second time.


Solution

  • On first click handleBroadcast event gets broadcasted and but haven't received by anyone, because when you press "GO" button, at that time state transition occurs and it loads template and its controller. When controller instantiated, it register the listener event using $on on handleBroadcast event.

    I'd suggest you that to wait to broadcast an event till controller & its underlying view gets render. This can be done by taking advantage of promise returned by $state.go method. Which completes when transition succeeds.

    Code

    $scope.buildDemo = function() {
        //state transition started.
        $state.go("MainPage", {
            "themeName": $rootScope.themeFolder
        }).then(function() {
            //state transition completed
            //controller instance is available & listener is ready to listen
            interfaceService.demo(device, template, integ, language);
            $rootScope.template = template;
            $rootScope.themeFolder = template;
        });
    }