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
source to share
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.
source to share
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
source to share