Angularjs: priority executing controllers - angularjs

I have some controllers and would like to share some datas from each others.
so I built a factory to pass those data ("anagType") from "AnagTypeController" to "CourseCatController", but the second controllers is parsed before the first one.
This is the HTML:
<div id="workArea" class="row">
<div class="col-md-6">
<div class="panel panel-info" ng-controller="Controller1">
...
</div>
</div>
<div class="col-md-6">
<div class="panel panel-warning" ng-controller="AnagTypeController">
...
</div>
<div class="panel panel-warning" ng-controller="Controller3">
...
</div>
</div>
<div class="clearfix"></div>
<div class="col-md-4">
<div class="panel panel-danger" ng-controller="CourseCatController">
...
</div>
</div>
<div class="col-md-4">
...
</div>
<div class="col-.md-4">
...
</div>
<div class="clearfix"></div>
</div> <!-- /#workArea-->
... and this is the angularjs:
app.controller('AnagTypeController', ['$scope', '$http', 'MsgBox', 'EmployeeMng',
function($scope, $http, MsgBox, EmployeeMng) {
$scope.anagType = [];
$scope.getList = function() {
$http({
method: "GET",
url: "../../xxx"
})
.success(function(data) {
$scope.anagType = data;
EmployeeMng.addAnagType($scope.anagType);
})
.error(function(data, status) {
console.log('ERROR AnagTypeController getList ' + data + ' ' + status);
});
};
$scope.getList();
}
]);
app.controller('CourseCatController', ['$scope', '$http', 'MsgBox', 'EmployeeMng',
function($scope, $http, MsgBox, EmployeeMng) {
$scope.anagType = [];
$scope.courseCats = [];
$scope.courseCatsObbl = [];
$scope.getCourseCats = function() {
$scope.anagType = EmployeeMng.anagType;
...
}
$scope.getCourseCats();
}
]);
Perhaps am I using angular in the wrong way?

Rather than making the call in one controller to set the data, you should move that code to the actual service itself.
All your controllers that need the data can then call the service to get the data.

Related

How to modify service url paramer in angularjs

I'm trying to modify the city parameter by searching for a city parameter, but I don't think it's possible to modify an angular service that way. So how would I be able to modify the service parameter in the controller? Any help would be amazing!
HTML:
<section ng-controller="MainController">
<form action="" class="form-inline well well-sm clearfix" >
<span class="glyphicon glyphicon-search"></span>
<input type="text" placeholder="Search..." class="form-control" ng-model="city" />
<button class="btn btn-warning pull-right" ng-click="search()"><strong>Search</strong></button>
</form>
<h1>{{fiveDay.city.name}}</h1>
<div ng-repeat="day in fiveDay.list" class="forecast">
<div class="day">
<div class="weekday">
<p>{{ day.dt*1000 | date}}</p>
<!-- <p>{{ parseJsonDate(day.dt)}}</p> -->
</div>
<div class="weather"><img ng-src="http://openweathermap.org/img/w/{{day.weather[0].icon}}.png"/></div>
<div class="temp">{{day.weather[0].description}}</div>
<div class="temp">Max {{ day.main.temp_max }}°</div>
<div class="temp">Min {{ day.main.temp_min }}°</div>
</div>
</div>
</section>
JS:
var app = angular.module('App', []);
app.controller('MainController', ['$scope', 'forecast', function($scope, forecast) {
forecast.city="orlando";
forecast.success(function(data) {
$scope.fiveDay = data;
});
}]);
app.factory('forecast', ['$http', function($http) {
var city = "orlando";
var key="a1f2d85f6babd3bf7afd83350bc5f2a6";
return $http.get('http://api.openweathermap.org/data/2.5/forecast?q='+city+'&APPID='+key+'&units=metric&cnt=5')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
City is a variable part in your forecast factory so need to pass it as an argument in function will be the recommended for you
Try this
var app = angular.module('App', []);
app.controller('MainController', ['$scope', 'forecast', function($scope, forecast) {
var city = "orlando";
forecast.getWeatner(city).success(function(data) {
$scope.fiveDay = data;
});
}]);
app.factory('forecast', ['$http', function($http) {
var key = "a1f2d85f6babd3bf7afd83350bc5f2a6";
return {
getWeatner: function(city) {
return $http.get('http://api.openweathermap.org/data/2.5/forecast?q=' + city + '&APPID=' + key + '&units=metric&cnt=5');
}
}
}]);
增加参数 callback , 回调:JSON_CALLBACK
$http.jsonp("http://api.openweathermap.org/data/2.5/forecast?q='+city+'&APPID='+key+'&units=metric&cnt=5&callback=JSON_CALLBACK").success(function(data){ ... });

How to get param from one controller to another?

My question is best explained when I straight go to the code.
HTML part:
<div class="panel panel-default post" ng-repeat="post in posts">
<div class="panel-body">
<div class="row">
<div class="col-sm-2">
<a class="post-avatar thumbnail" href="/profile#/{[ post.profileID ]}">
<div class="text-center">{[ user.fullname ]}</div>
</a>
</div>
</div>
</div>
When I click on the /profile#/{[ post.profileID ]} link - it takes me to the profile page. All good here.
However, I am using ngView so I have separated it like this:
<div class="col-md-3">
<div>Some HTML stuff</div>
</div>
<div class="col-md-6">
<div ng-view></div>
</div>
<div class="col-md-3">
<div>Some HTML stuff</div>
</div>
My ngView makes use of the /profile#/{[ post.profileID ]} param and I use it to display whatever I have to display.
The problem:
I can get the profileID param in my angular controller but once I get it, how will I be able to pass it onto other controllers?
My controller looks like the below:
var profileApp = angular.module('profileApp', ['ngRoute']);
profileApp.config(function($routeProvider) {
$routeProvider
.when('/:id', {
templateUrl : 'partial/profile/feed.html',
controller : 'mainController'
})
.when('/posts:id', {
templateUrl : 'partial/profile/posts.html',
controller : 'postsController'
});
});
profileApp.controller('mainController', ['$scope', '$http', '$routeParams', function($scope, $routeParams){
console.log($routeParams.id);
}]);
profileApp.controller('postsController', ['$scope', '$routeParams', function($scope, $routeParams){
console.log($routeParams.id);
}]);
As you can see, I get get the param passed from the HTML link and use it in the mainController but how will I get the param to be a link in the col-md-3 (just like the original /profile#/{[ post.profileID ]})?
Hope this makes sense. It's has been driving me nuts!
Thanks
Why don't you just edit your partial HTML pages and put the columns in it.
For partial/profile/feed.html :
<div>
<div class="col-md-6">
<div>feed stuff</div>
</div>
<div class="col-md-3">
</div>
</div>
And partial/profile/posts.html could be :
<div>
<div class="col-md-6">
</div>
<div class="col-md-3">
<div>posts stuff</div>
</div>
</div>
So I did some research into this and I just ended up using services.
See below for the answer:
profileApp.service('globalParams', function() {
var profileID = '';
return {
getProfileID: function() {
return profileID;
},
setProfileID: function(value) {
profileID = value;
}
};
});
You then pass the service into the dependencies in the controllers, like below:
profileApp.controller('mainController', ['$scope', 'globalParams', function($scope, globalParams){
//some code
};
And you can call the functions for getting and setting the variables.

Not able to Access Services on Two Controller AngularJs

I Need to use same data on Two different Controller, One is page while other is Modal Popup. I created service which will perform $http.get to pull data. However, when I apply service to Modal Popup, it stops loading and even data is not load anywhere.
My Service
(function(){
'use strict';
angular.module('sspUiApp.services')
.service('AdUnitService', ['$http', '$rootScope', 'API_URL', function($http, $scope, API_URL) {
var data = $http.get('data/selectAdUnits.json');
return {
getAdFormats: function() {
console.log("inside function");
return data;
},
setAdFormats: function(value) {
}
}
}]);
})();
My Both Controller with Services added.
(function(){
'use strict';
angular.module('sspUiApp.controllers')
.controller('AdUnitFormatCtrl', ['$scope', '$state', 'AdUnitService', function ($scope, $state, AdUnitService) {
$scope.details = AdUnitService.getAdFormats();
}])
.controller('ModalDemoCtrl', ['AdUnitService', function ($scope, $uibModal, AdUnitService) {
$scope.open = function (size) {
// $scope.details = AdUnitService.getAdFormats();
$scope.$modalInstance = $uibModal.open({
scope: $scope,
templateUrl: 'views/select_ad_format.html',
size: size,
});
};
$scope.cancel = function () {
$scope.$modalInstance.dismiss('cancel');
};
$scope.details = AdUnitService.getAdFormats();
alert($scope.details);
}])
})();
And HTML
<div id="selectAdFormats" ng-controller="ModalDemoCtrl">
<div class="container">
<div class="ad-format-section">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-2 col-xs-6 selectedAdFormatData" ng-repeat="frmt in details.adformat">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-center">
<img ng-src="../images/{{ frmt.ad_image }}" ng-if="frmt.ad_image"/>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-center">
<span class="formatName">{{ frmt.name }}</span>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-center">
<span class="resSize">{{ frmt.size }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
angular.module('sspUiApp.services')
angular.module('sspUiApp.controllers')
Your service is in a different module, that's why you can't get to it, if you declare it into the same module it should work
Option 2:
Include your second module sspUiApp.services in your decleration of sspUiApp.controllers
for more info: Angular js seperation to different modules in different js files
Update:
var data = $http.get('data/selectAdUnits.json');
return {
getAdFormats: function() {
console.log("inside function");
return data;
},
setAdFormats: function(value) {}
}
The problem is is that data is asynchronious and you don't treat it like so:
$scope.details = AdUnitService.getAdFormats();
alert($scope.details);
You try to alert a promise, instead of waiting for it to resolve and alerting the result, if you change it into the following it should work:
AdUnitService.getAdFormats().then(function(details) {
alert(details);
});
This way angular will wait on the result before executing the code.
More info about Angular promises here: https://docs.angularjs.org/api/ng/service/$q

Why won't my view template bind to a scope variable with AngularJS?

My view is:
<div class="container" ng-controller="MyController">
<div class="row">
<div class="col-md-8">
<textarea class="form-control" rows="10" ng-model="myWords" ng-change="parseLanguage()"></textarea>
</div>
<div class="col-md-4" ng-show="sourceLanguage !== null">
Language: {{ sourceLanguage }}
</div>
</div>
</div>
My controller is:
webApp.controller('MyController', [
'$scope', '$rootScope', 'TranslateService', function($scope, $rootScope, CodeService) {
$scope.init = function() {
return $scope.sourceLanguage = null;
};
$scope.parseLanguage = function() {
return TranslateService.detectLanguage($scope.myWords).then(function(response) {
console.log($scope.sourceLanguage);
$scope.sourceLanguage = response.data.sourceLanguage;
return console.log($scope.sourceLanguage);
});
};
return $scope.init();
}
]);
The console logs show the right data. But in the view, sourceLanguage never updates. Why would this be?
In case the promise you are evaluating is not part of the Angular context you need to use $scope.$apply:
$scope.parseLanguage = function() {
TranslateService.detectLanguage($scope.myWords).then(function(response) {
$scope.$apply(function() {
$scope.sourceLanguage = response.data.sourceLanguage;
});
});
};

Having a hard time inheriting scope from parent in AngularJS

So I have the following two controllers, a parent and a child, and I need a value that is dynamically added to the parent scope passed on into the child scope. I really can't understand how the service injection works either. Here is my parent controller:
'use strict';
angular.module("myApp").controller("singleTopicController", ["RestFullResponse", "Restangular", "localStorageService", "$scope", "$window", "$stateParams", function(RestFullResponse, Restangular, localStorageService, $scope, $window, $stateParams){
var topics = Restangular.one('topics', $stateParams.id);
var Topics = topics.get({},{"Authorization" : localStorageService.get('***')}).then(function(topic){
$scope.topic = topic;
$scope.topic.id = topic.id;
$window.document.title = 'Example | ' + $scope.topic.topic_title;
console.log($scope.topic);
});
}]);
And my child controller which needs the topic.id to work.
'use strict';
angular.module("myApp").controller("commentSingleController", ["RestFullResponse", "Restangular", "localStorageService", "$scope", "$state", "$stateParams", "$timeout", function(RestFullResponse, Restangular, localStorageService, $scope, $state, $stateParams, $timeout){
$scope.topic = {};
var oneTopic = Restangular.one('topics', $scope.topic.id);
oneTopic.get({}, {"Authorization" : localStorageService.get('***')}).then(function(topic) {
topic.getList('comments', {}, {"Authorization" : localStorageService.get('***')}).then(function(comments){
$scope.comments = comments;
console.log($scope.comments);
});
});
$scope.isCollapsed = true;
var comments = Restangular.all('comments');
$scope.commentData = {
//topic_id: $scope.parent.topic.id
};
$scope.postComment = function(mood) {
$scope.commentData.mood = mood;
comments.post($scope.commentData, {}, {"Authorization" : localStorageService.get('***')}).then(function(response){
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
}, function(response){
$scope.error = response.data.message;
})
};
}]);
If I add
console.dir($scope.$parent);
to the child controller, topic is obviously there.
But if I try
console.dir($scope.$parent.topic);
I get undefined.
I tried wrapping the Restangular.get() of the child controller in a watcher but that didn't do anything.
$scope.$watch('topic', function{
Restangular.one() ...})
Where am I going wrong here.
<div class="main-left-column">
**<div ng-controller="singleTopicController">** //my main controller
<div class="topic-full">
<div class="topic-left">
<div class="topic-left-inner">
<a ui-sref="main.topic({id: topic.id})"><h4>{{ topic.topic_title }}</h4></a>
<hr>
<img ng-src="{{ topic.image_url }}" class="img-responsive img-topic" tooltip="{{ topic.topic_title}}"/>
<hr ng-if="topic.image_url">
<p>{{ topic.topic_content }}</p>
</div>
</div>
<div class="topic-right">
**<div class="topic-right-inner" ng-controller="commentSingleController">** //child controller
<img ng-src="{{ topic.profile_pic }}" width="60px" class="profile-pic"/>
<div class="topic-data">
<h4 class="topic-data">{{ topic.author_name }}</h4>
<h5 class="topic-data">- posted on {{ topic.created_at }}</h5>
</div>
<div class="comment-count">
<div class="comment-count-mood red" tooltip="Negative comments"><p>{{ topic.comments_angry }}</p></div>
<div class="comment-count-mood yellow" tooltip="Neutral comments"><p>{{ topic.comments_sad }}</p></div>
<div class="comment-count-mood green" tooltip="Positive comments"><p>{{ topic.comments_happy }}</p></div>
</div>
<div class="clear"></div>
<hr>
<p ng-if="comments.length == 0">No comments</p>
<div class="line-through">
<div ng-repeat="comment in comments">
<div class="comment-left">
<img ng-src="{{ comment.profile_pic }}" width="40px" class="comment-pic"/>
<div class="comment-mood" ng-class="{'red': comment.mood == 2, 'yellow': comment.mood == 1, 'green': comment.mood == 0}"></div>
</div>
<div class="comment-right">
<h4 class="comment-data">{{ comment.author_name }}</h4>
<p>{{ comment.comment }}</p>
</div>
<div class="clear"></div>
<hr class="dotted" ng-if="!$last">
</div>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
</div>
UPDATE: Added HTML. Controller wrappers are in asterisks.
Your topic won't be created until your .get in your parent controller resolves, which is probably after the initialisation of the child controller.
If you remove the $scope.topic = {} from the child controller and add a $watch for topic.id you should be able to use the id in there.
Really you shouldn't need $scope.$parent as $scope should have everything the parent does unless it's been hidden by something in the child scope or there's an isolate scope in the way (there isn't in this case).

Resources