Angular passing parameters from one controller to another - angularjs

Im a newbie in angular, trying to learn the language.
Got the following code: http://plnkr.co/edit/fuVb0mzhmDCKr1xKp7Rn?p=preview
Have a tab:
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.when
('/jobs', {templateUrl: 'jobs-partial.html', controller: JobsCtrl }).
when
('/invoices', {templateUrl: 'invoices-partial.html', controller: InvoicesCtrl }).
when
('/payments', {templateUrl: 'payments-partial.html', controller: PaymentsCtrl }).
otherwise({redirectTo: '/jobs'});
// make this demo work in plunker
$locationProvider.html5Mode(false);
}]);
I would like to be able to access the selected tab from one the panel. How can I send parameters to the tab controllers?

Create a service that will set a value and return it:
.service('shared', function() {
var myValue;
return {
setValue: function(value) {
myValue = value;
},
getValue: function() {
return myValue;
}
}
});
Then inject it into both your controllers:
.controller('Ctrl1', ['shared', function(shared)......
.controller('Ctrl2', ['shared', function(shared)......
And then set the value from Ctrl1:
shared.setValue('somevalue');
And in Ctrl2 you can just retrieve the value:
var mySharedValue = shared.getValue();

You can create a Service or Factory, inject that in to your TabsCtrl, save the currentTab state in that service in ng-click. Inject the same service in your Page controllers like JobsCtrl
app.factory('MyService',function(){
var currentTab ;
return {
setCurrentTab : function(tab){
currentTab = tab;
},
getCurrentTab : function(tab){
return currentTab;
}
};
});
Update your TabsCtrl like below
function TabsCtrl($scope, $location, MyService) {
// removing other code for brevity
$scope.selectedTab = $scope.tabs[0];
// saving the default tab state
MyService.setCurrentTab($scope.tabs[0]);
$scope.setSelectedTab = function(tab) {
$scope.selectedTab = tab;
// saving currentTab state on every click
MyService.setCurrentTab(tab);
}
}
In your JobsCtrl, inject the same MyService and retrieve the cached tab state like below
function JobsCtrl($scope, MyService) {
var currentTab = MyService.getCurrentTab();
alert(currentTab.label);
}
Here's an updated Plunker with the above changes.

Related

Using angularjs route how can I get a scope value into another controller?

I have project which is a single page application.So that I am using angular js route.
In the first controller I have a $scope value.The same value i have to use in the other controller
here is my controller.js file
var module = angular.module("sampleApp", ['ngRoute']);
module.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/route1', {
templateUrl: 'http://localhost/MyfirstApp/welcome',
controller: 'RouteController1'
}).
when('/route2', {
templateUrl: 'http://localhost/MyfirstApp/result',
controller: 'RouteController2'
}).
otherwise({
redirectTo: '/'
});
}]);
module.controller("RouteController1", function($scope)
{
$scope.value="Athira"
})
module.controller("RouteController2", function($scope) {
$scope.text=$scope.value + "Sandeep"
})
In the result page it should show as 'Athira Sandeep'
thank you for any kind of help
Use a service to share data among controllers .
Another option could be event emitters which i personally am not a fan because it populates the rootScope (in this case) with a lot of events.
What you could do it
angular.module('app',[])
.factory('SharedScope',function(){
var fac = this;
var scope = "";
var sharedScope = {
getScope : function(){
return fac.scope;
},
setScope: function(scope){
fac.scope = scope
}
};
return sharedScope;
})
.controller('Ctrl1',function('SharedScope'){
SharedScope.setScope("Angular");
})
.controller('Ctrl2',function('SharedScope'){
var data = SharedScope.getScope();
$scope.text = data + " is awesome"; //would get Angular is awesome
});
Hope this helps.

$scope.myVar updates but not in the view

I have a template nested in an other template (menu is the parent template) which share the same controller. My Controller gets the value from a service called counterOperations. Althought $scope.total seems to be updating in console.log the view does not update the value.
Controller
.controller('ListController', function ($scope, $http, $state, counterOperations, userService) {
//Some code
$scope.add = function (index) {
$scope.total = counterOperations.getTopCounter();
console.log($scope.total);
};
})
Templates
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: "ListController"
})
$stateProvider
.state('app.list', {
url: '/list',
views: {
'products': {
templateUrl: 'templates/product-list.html',
controller: "ListController"
}
}
})
with ng-click I trigger a function which calls some functions from a service
The view variable for menu
<span>{{total}}</span>
I have tried to update the value this way but nothing changes
setTimeout(function() {
$scope.total = counterOperations.getTopCounter();
}, 1000);
Any ideas ?
Here your 2 states "app" and "app.list" have same controller, when you change state from "app" to "app.list" regardless of same controller controller will reinstantiated which means value in $scope.total variable will lost and will reset in next state.
Solution -
Assign total to $rootScope if you want it in other state too
$scope.add = function (index) {
$rootScope.total = counterOperations.getTopCounter();
};
.controller('ListController', function ($scope, $http, $state, counterOperations, userService) {
//Some code
$scope.total = ''; //or $scope.total = 0;
$scope.add = function (index) {
$scope.total = counterOperations.getTopCounter();
console.log($scope.total);
};
})
Check if the above works for you?

Ajax data via ngResource does not reflect after ngView update through ngRoute :(

I tried a lot and could not find proper answer which can solve my problem. Hope someone will help me out.
app.controller('MainController', ['$scope', 'MainService', 'CONSTANTS', '$routeParams', '$location',
function($scope, MainService, CONSTANTS, $routeParams, $location) {
$scope.indexAction = function() {
MainService.query({format: 'json'}, function(data){
$scope.data = data;
**This data still there when viewAction get call.**
});
}
$scope.newAction = function($event) {
$scope.isNew = true;
angular.isDefined($event)? $event.preventDefault() : false;
if(angular.isDefined($event)) {
var postData = $('#form').serialize();
MainService.save({format: 'json'}, postData, function(data, responseHeader){
var loc = responseHeader('location');
var r = /\d+/;
var dataId = loc.match(r);
$scope.viewAction(dataId[0]);
});
}
else {
$location.path('new');
}
}
$scope.viewAction = function(ObjOrId) {
var dataId = null;
if(angular.isObject(ObjOrId)) {
dataId = ObjOrId.id;
$scope.data = ObjOrId;
$location.path('view/'+dataId);
}
else {
dataId = ObjOrId;
MainService.get({Id: ObjOrId, format: 'json'}, function(data) {
$scope.data = data;
$location.path('view/'+dataId);
});
}
}
$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
});
}
]);
app.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.
when('/new', {
templateUrl: 'abc.html',
controller: 'MainController'
}).
when('/view/:Id', {
templateUrl: 'xyz.html',
controller: 'MainController'
}).
otherwise({
templateUrl: 'list.html'
})
$locationProvider.html5Mode({
enabled: false
});
}
])
The data which comes in list.html with the help of indexAction that still exists when view route called and I am calling viewAction and loading data from ajax but that new data does not get updated in the view.
Please help!!
Your location.path looks like $location.path('new') when they should look like $location.path('/new');
Your other one looks like $location.path('view/'+dataId) when it should look like $location.path('/view'+ dataId);
I found the answer, I was using ng-model in form template and that was updating the $scope.data object without submitting the form itself, So i changed input directive ng-model to ng-value and while migrating to view template there i am able to get the data.

How to call one controller array in another controller

I have created countryApp module. I have created "names" array in aboutCtrl.
I want to access "names" array in contactCtrl in insertContact function.
var countryApp = angular.module('countryApp', ['ngRoute']);
countryApp.config(function($routeProvider) {
$routeProvider.
when('/', {
template: '<h1>Home</h1>',
controller: 'homeCtrl'
}).
when('/aboutus', {
templateUrl: 'aboutus.html',
controller: 'aboutCtrl'
}).
when('/contact', {
templateUrl: 'cotacts.html',
controller: 'contactCtrl'
}).
otherwise({
redirectTo: '/'
});
});
countryApp.controller('homeCtrl', function($scope) {
});
countryApp.controller('aboutCtrl', function($scope) {
$scope.names = [{name:'venu',number:'22222',sex:'male'},{name:'Aishu',number:'1111',sex:'female'},{name:'Milky',number:'2222',sex:'female'}]
});
countryApp.controller('contactCtrl', function($scope) {
$scope.greeting = 'Hello, World!';
$scope.insertContact = function () {
alert(names);
}
$scope.resetContact = function () {
}
});
To expand on Claies' solution with actual code:
countryApp.controller('aboutCtrl', function($scope, dataService) {
/* If you're binding the values into your HTML,
you need to $watch the service variable 'names' */
$scope.$watch(function() { return dataService.names }, function() {
$scope.names = dataService.names;
});
dataService.names = [{name:'venu',number:'22222',sex:'male'},{name:'Aishu',number:'1111',sex:'female'},{name:'Milky',number:'2222',sex:'female'}]
});
countryApp.controller('contactCtrl', function($scope, dataService) {
/* You can place the same watch as in aboutCtrl here if
you're displaying stuff in HTML that's related to this controller */
$scope.greeting = 'Hello, World!';
$scope.insertContact = function () {
alert(dataService.names);
}
$scope.resetContact = function () {
}
});
countryApp.service('dataService', function() {
var dataObj = {};
dataobj.names = [];
return dataObj;
});
Do notice the comments about $watching the service variable; if you want to display the values in the view through a $scope variable, you'll need to $watch the corresponding service variable or the $scope variable won't be updated when the value of the service variable changes.
If you want to communicate between two controllers, then please take reference of the following fiddle:
Fiddle : http://jsfiddle.net/VaibhavP17/nky45/
It shows how to communicate between the two controllers and also the nuances of events. I hope this helps :)

Why variable is not available in controller?

I have HTML code:
<div ng-controller="ProfileLeftMenu">
<li ng-class="{'active':selectedTab == 'personal'}" ng-click="selectedTab = 'personal'" class="">Personal
</li>
</div>
And controller:
$scope.selectedTab = 'first';
if ($routeParams.page) {
ajax.get(page, function (CbData) {
$scope.selectedTab = page;
});
}
So, if do:
{{selectedTab}}
in template HTML get always: first
You need to update your $scope variable with the new $routeParams just after the change in route. For that you can listen for the$routeChangeSuccess event. Try this:
DEMO
app.js
var app = angular.module('plunker', ['ngRoute']);
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/test/:page', {
templateUrl: function(params) {
return 'pidat.html';
},
controller: 'MainCtrl'
});
}
]);
app.controller('MainCtrl', ['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
// when controller is loaded params are empty
console.log('on controller load $routeParams', $routeParams);
$scope.name = 'World';
// only after you have transitioned to the new
// route will your $routeParams change so we
// need to listen for $routeChangeSuccess
$scope.$on('$routeChangeSuccess', function(){
console.log('on $routeChangeSuccess load $routeParams', $routeParams);
if ($routeParams.page) {
$scope.name = $routeParams.page;
}
});
}]);
So for your original example you would probably have to do something like this:
$scope.selectedTab = 'first';
$scope.$on('$routeChangeSuccess', function(){
if ($routeParams.page) {
ajax.get(page, function (CbData) {
$scope.selectedTab = page;
});
}
});
Use the angular $http service ($http.get()), not ajax.get(). Otherwise, Angular isn't aware of the change you make to the scope once the HTTP response comes and the callback is executed, unless you call $scope.$apply().

Resources