Why won't $location.path trigger a $routeChangeStart in the controller? - angularjs

My test has:
it("should clear the search field when the URL changes", function() {
createController();
$scope.init();
$scope.searchTerm = 'some term';
$location.path('/source');
$rootScope.$apply();
expect($scope.searchTerm).toBe('');
});
My controller is:
angularMoonApp.controller('SearchController', ['$scope', '$location', function ($scope, $location) {
$scope.init = function() {
$scope.$on('$routeChangeStart', function(next, current) {
$scope.searchTerm = '';
});
}
$scope.init();
}]);
Seems simple enough! So why won't that trigger when I Change the location in the test?

You need to inject $route, since $routeChangeStart is an event triggered by $route.
angularMoonApp.controller('SearchController', ['$scope', '$location', '$route', function ($scope, $location, $route) {
Without knowing your use case, if you just need to detect that the url changed, you can listen for $locationChangeStart instead. $locationChangeStart is fired from $location, so you would not need to inject any new dependencies.

Related

How to send events with AngularJs $emit properly

I want to send data from one controller to another at a certain point. I have looked at the docs and googled before for solutions before posting. But can`t seem to get it to work properly.
I know $emit is for sending events up the scope hierarchy and $braodcast is for telegraphing downwards.
var app = angular.module('App.Controllers', ['ui.bootstrap'])
.controller('FordelaPaBetankandeCtrl',
['$rootScope', '$scope',
function ($rootScope, $scope) {
$scope.$on("delatYrkande", function (selectedValue) {
});
}])
.controller('UtskottCtrl',
['$rootScope', '$scope'
function ($rootScope, $scope) {
}])
.controller('TidlinjeCtrl',
['$rootScope', '$scope'
function ($rootScope, $scope) {
}])
.controller('UserInfoCtrl', ['$scope',
function ($scope){
}])
.controller('VisaSammantradesplanCtrl', ['$rootScope', '$scope',
function ($rootscope, $scope) {
}])
.controller('HanteraGrunddokumentCtrl',
['$rootScope', '$scope',
function ($rootScope, $scope) {
$scope.Emit = function (selectedValue) {
$scope.$emit("delatYrkande", selectedValue);
}
}]);
One approach is to broadcast from $rootScope:
$scope.Emit = function (selectedValue) {
̶$̶s̶c̶o̶p̶e̶.̶$̶e̶m̶i̶t̶(̶"̶d̶e̶l̶a̶t̶Y̶r̶k̶a̶n̶d̶e̶"̶,̶ ̶s̶e̶l̶e̶c̶t̶e̶d̶V̶a̶l̶u̶e̶)̶;̶
$scope.$root.$broadcast("delatYrkande", selectedValue);
}
For more information, see
AngularJS Developer Guide - Scope Events Propagation
AngularJS scope API Reference - $root
AngularJS scope API Reference - $broadcast

how to passing data from one controller to another controller using angular js 1

hi all i using angular js i need to transfer the value from one page controller to another page controller and get that value into an a scope anybody help how to do this
code Page1.html
var app = angular.module("app", ["xeditable", "angularUtils.directives.dirPagination", "ngNotify", "ngCookies","ngRoute"]);
app.controller('Controller1', ['$scope', '$http', '$window', '$filter','$notify','$cookieStore',
function ($scope, $http, $window, $filter, $notify, $cookieStore)
{
$scope.Message="Hi welcome"
}]);
now i want to show scope message into page2 controller
var app = angular.module("app", ["xeditable", "angularUtils.directives.dirPagination", "ngNotify", "ngCookies","ngRoute"]);
app.controller('Controller2', ['$scope', '$http', '$window', '$filter','$notify','$cookieStore',
function ($scope, $http, $window, $filter, $notify, $cookieStore)
{
///here i want get that scope value
}]);
You can use $rootScope instead of $scope:
// do not forget to inject $rootScope as dependency
$rootScope.Message="Hi welcome";
But the best practice is using a service and share data and use it in any controller you want.
You should define a service and write getter/setter functions on this.
angular.module('app').service('msgService', function () {
var message;
this.setMsg = function (msg) {
message = msg;
};
this.getMsg = function () {
return message;
};
});
Now you should use the setMeg function in Controller1 and getMsg function in Controller2 after injecting the dependency like this.
app.controller('Controller1', ['$scope', '$http', '$window', '$filter','$notify','$cookieStore', 'msgService',
function ($scope, $http, $window, $filter, $notify, $cookieStore, msgService)
{
$scope.Message="Hi welcome"
msgService.setMsg($scope.Message);
}]);
app.controller('Controller2', ['$scope', '$http', '$window', '$filter','$notify','$cookieStore', 'msgService',
function ($scope, $http, $window, $filter, $notify, $cookieStore, msgService)
{
///here i want get that scope value
console.log('message from contoller 1 is : ', msgService.getMsg());
}]);
You should use services for it .
Services
app.factory('myService', function() {
var message= [];
return {
set: set,
get: get
}
function set(mes) {
message.push(mes)
}
function get() {
return message;
}
});
And in ctrl
ctrl1
$scope.message1= 'Hi';
myService.set($scope.message1);
ctrl2
var message = myService.get()
Sharing data from one controller to another using service
We can create a service to set and get the data between the controllers and then inject that service in the controller function where we want to use it.
Service :
app.service('setGetData', function() {
var data = '';
getData: function() { return data; },
setData: function(requestData) { data = requestData; }
});
Controllers :
app.controller('Controller1', ['setGetData',function(setGetData) {
// To set the data from the one controller
$scope.Message="Hi welcome";
setGetData.setData($scope.Message);
}]);
app.controller('Controller2', ['setGetData',function(setGetData) {
// To get the data from the another controller
var res = setGetData.getData();
console.log(res); // Hi welcome
}]);
Here, we can see that Controller1 is used for setting the data and Controller2 is used for getting the data. So, we can share the data from one controller to another controller like this.

How can I run function from another controller so scope is updated in angular?

In the example below, how can I run getData from another controller and have the scope variable in the view updated?
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);
app.controller('MyController2', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
///// ?????? How to get $scope.myVarialbe updated from the getData call?
});
}]);
Using $broadcast and $on :
$broadcast dispatches an event name downwards to all child scopes (and their children) and notify to the registered $Scope listeners. The event life cycle starts at the scope on which $broadcast was called. All listeners for the event on this scope get notified.
$on listen on events of a given type. It can catch the event dispatched by $broadcast
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
$scope.$on('variableChanged',function(event, value) {
$scope.myVariable = value;
};
}]);
app.controller('MyController2', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.$broadcast('variableChanged', response.data);
});
}]);
angular.module('app').controller('nav', function($scope,$http) {
$rootScope.$on("CallMethodNavController", function(){
$scope.navMethod();
});
$scope.navMethod=function(){
$http.get('/players').then(function(data) {
$scope.numOfPlayers = data.players.length;
}
});
});
then in the second controller you call this method once a player is added like so:
$rootScope.$emit("CallMethodNavController", {});

why do i need $timeout for a location change in this case?

I have the following code:
angular.module('DemoApp')
.controller('NavbarCtrl', ['$scope', '$rootScope', '$location', '$timeout', function($scope, $rootScope, $location, $timeout) {
$scope.logout = function() {
$rootScope.user = null;
$location.path("/login");
};
}]);
The problem is that when logout is called, the location does not change. However the following code works (notice the use of $timeout):
angular.module('DemoApp')
.controller('NavbarCtrl', ['$scope', '$rootScope', '$location', '$timeout', function($scope, $rootScope, $location, $timeout) {
$scope.logout = function() {
$rootScope.user = null;
$timeout(function() {
$location.path("/login");
});
};
}]);
Can somebody tell my why this is?
edit:
The HTML looks like this and is inside the NavbarCtrl controller element:
<i class="fa fa-sign-out"></i><br/>Abmelden
The thing that was wrong is the HTML: href="#" causes a location change that somehow cannot be changed again by $location.path(). Changing the HTML to href="" removes the necessity to use $timeout

updating ng-model of one angular js controller from another angular js controller

Angular Experts,
I am new to Angular Js and trying to update input in one controller with value from the input in another controller. I am not sure whether it is even possible or not?
I have created js fiddle link just to give an idea.
http://jsfiddle.net/MwK4T/
In this example when you enter a value in controller 2's input, and click 'Set Value it does update biding with <li></li> but does't not update input of the controller 1.
Thanks in advance
I made it working using $broadcast. And it is working like a charm.
I did something like this.
App.controller('Ctrl1', function($rootScope, $scope) {
$rootScope.$broadcast('msgid', msg);
});
App.controller('Ctrl2', function($scope) {
$scope.$on('msgid', function(event, msg) {
console.log(msg);
});
});
Thanks for helping me out.
Best way would be to use the service, we need to avoid the event as much we can, see this
var app= angular.module('testmodule', []);
app.controller('QuestionsStatusController1',
['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
$scope.myservice = myservice;
}]);
app.controller('QuestionsStatusController2',
['$rootScope', '$scope', 'myservice',
function ($rootScope, $scope, myservice) {
$scope.myservice = myservice;
}]);
app.service('myservice', function() {
this.xxx = "yyy";
});
Check the working example

Resources