Angular View without refresh with new data

I'm a bit of an Angular newbie, so sorry if it's obvious.

I have a backend that returns an array of objects. After I retrieve them, I go to the next page and I need to display a checkbox for each of the objects. I can restore them successfully, so I changed the browser location to the next page where the checkboxes should be showing but nothing. I tried using $ scope. $ Apply () however it throws an error stating that the digest is already taking place, but I think this is correct because I used ng-click which is wrapped in the $ scope. $ Apply () I think

I can see that services are printing to the console successfully, however they are not showing on the page. Not sure what I am doing wrong here?

In my starting view:

<form>
    <div class="form-group">
        <select id="main_service" name="main_service" class="form-control" ng-model="mainService">
             <option>Please Select...</option>
             <option ng-repeat="service in mainServices" value="{[{service}]}">{[{service}]}</option>  
        </select>
    </div>
    <div class="form-group">
        <button class="btn btn-primary" type="submit" ng-click="updateServices()">Continue</button>
    </div>
</form>

      

in my controller: var professionalSignupControllers = angular.module ('professionalSignupCtrls', [])

professionalSignupControllers.controller('professionalQuestions', function($scope, $http, Service, $sce, $routeParams,$location){
$scope.mainService = "";
$scope.services = [];

$scope.updateServices = function(){
    Service.getServices($scope.mainService)
        .success(function(data) {
            $scope.services = data
            console.log($scope.services)
            //$scope.$apply(); throws digest error!
            $location.path( '/services' );
        })
        .error(function(data, error) {
            event.preventDefault();
            alert("Oh Dear")
        });
};

      

})

In my services, partially:

<div>
    <div ng-repeat="service in services" class="checkbox">
        <label><input type="checkbox" name="service[]" value="{[{service.id}]}" ng-model="user.services">{[{service.label}]}</label>
    </div>
</div>

      

My servicesServices (wrong name):

angular.module('servicesService', [])

.factory('Service', function($http) {

    return {
        getServices : function(tag) {
            return $http.get('/api/service?searchTerm='+tag)
        }
    }
});

      

My app config:

app.config(['$routeProvider', '$locationProvider','$interpolateProvider',
function($routeProvider,$locationProvider,$interpolateProvider) {

    $routeProvider.
        when('/start', {
            templateUrl: '/js/partials/start-professional-questions.html',
            controller: 'professionalQuestions'
        }).
        when('/services', {
            templateUrl: '/js/partials/services-professional-questions.html',
            controller: 'professionalQuestions'
        }).
        otherwise({
            redirectTo: '/start'
        });

    $interpolateProvider.startSymbol('{[{').endSymbol('}]}');

    }
]);

      

I am using {[{}]} for interpolation as it would otherwise be a class with Blade syntax

+3


source to share


3 answers


You are in the area angular

so you don't need to run $scope.$apply()

. it is only required when you are outside of angular scope.

Concerning your problem:

You are returning a promise object in a service. Thus, the returned data is only available in this controller. If you go to the next page, then it will not be available.

If you want to share data, you must store it inside the service.

In your service:

 angular.module('servicesService', [])

.factory('Service', function($http, $q) {
    var data;
    return {
        getData: function() {
           return data;
        },
        getServices : function(tag) {
            var defer = $q.defer();
            $http.get('/api/service?searchTerm='+tag).then(function(response) {
                data = response;
                defer.resolve(response);
            });
            return defer.promise;
        }
    }
});

      



Now in your other controller, you can access the data with getData()

In your controller, you may need to change it a bit:

$scope.updateServices = function(){
    Service.getServices($scope.mainService).then(function(data){
            $scope.services = data
            console.log($scope.services)
            $location.path( '/services' );
        }, function(data, error) {
            event.preventDefault();
        });
};

      

In your second controller, you can access it via Service.getData()

Since you are using the same controller for both views, you need to use a condition if

to validate route

and retrieve the data separately. Alternatively, you can start the service call again.

+4


source


even if both routes have the same controller name, this does not mean that they are the same ..

it is like two separate instances of the same class and the data for each instance will always be different. so installing it in one place and using it in another is not the way to go.

You need a service to exchange data between controllers

just to develop a comment ... you can use services to exchange data between controllers. this video is from egghead.io



egghead.io is a great resource for beginners with angualrjs.

this is how this service should look like

app.service('productService', function() {
  var personList = [];

  var add = function(newObj) {
      personList.push(newObj);
  }

  var get = function(){
      return personList;
  }

  return {
    add: add,
    get: get
  };

});

      

above is an example making it easy to exchange data between controllers in my application

+1


source


I think you are not using the same ng model, double check your ng-contoller tag. And you meant 2

try it

if (!$scope.$$phase)
    $scope.$apply();

      

0


source







All Articles