As stated in the title, I'm trying to pass a value (ID) from one controller (PerksApprovalController) going to another controller (PerksDetailsController). Please find below image for visual reference.
What I want to do is, when I click the "Show Details" button, it will redirect me to another page to display the details of the Control Number that I pass.
Below is my implementation.
Show Details Button Code
<button class="btn btn-xs" ng-click="vm.showDetails(p.ControlNumber)">Show Details</button>
PerksApprovalCtrl.js
(function () {
'use strict';
var app = angular.module('app');
PerksApprovalController.$inject = ['$window', 'app.perksService', 'app.sharedValuesFactory'];
app.controller('app.perksApprovalController', PerksApprovalController);
function PerksApprovalController($window, PerksService, SharedValuesFactory) {
/* jshint validthis:true */
var vm = this;
vm.showDetails = function (controlNo) {
SharedValuesFactory.setControlNo(controlNo);
$window.location = '/PerksDetails/PerksView';
}
}
})();
PerksDetailCtrl.js
(function () {
'use strict';
var app = angular.module('app');
PerksDetailController.$inject = ['$scope', '$http', '$q', '$window', 'app.perksService', 'app.sharedValuesFactory'];
app.controller('app.perksDetailController', PerksDetailController);
function PerksDetailController($scope, $http, $q, $window, PerksService, SharedValuesFactory) {
var vm = this;
PerksService.getPerksItems(SharedValuesFactory.getControlNo()).then(function (response) {
vm.perksItemDetails = response.data;
});
}
})();
I have created a service just like what they suggested in some topics here.
sharedValuesFactory.js
(function () {
'use strict';
var app = angular.module('app');
// SharedValuesFactory.$inject = ['$http'];
app.factory('app.sharedValuesFactory', SharedValuesFactory);
function SharedValuesFactory() {
var controlNoShared;
return {
setControlNo: function (c) {
this.controlNoShared = c;
},
getControlNo: function () {
return this.controlNoShared;
}
}
}
})();
My problem now is, everytime the details page is loaded, SharedValuesFactory.getControlNo() returns undefined. Looks like SharedValuesFactory is reset after the redirect or page load.
Any idea on how to properly pass a value from one controller to another?
TIA
I have a specific way of passing value in between Controllers. Hope it does the trick!
Note:
Not Sure what sharedValuesFactory.js is being used for! Assumming You are using this service to pass Data in between Controllers only. According to me only One service suites your requirement i.e PerksService.
The button passes the value (ID) of "ControlNumber".
<button class="btn btn-xs" ng-click="vm.showDetails(p.ControlNumber)">Show Details</button>
In PerksApprovalCtrl.js pass the controlNo you are getting on button click to the url of the page as in of a different view
PerksApprovalCtrl.js
(function () {
'use strict';
var app = angular.module('app');
PerksApprovalController.$inject = ['$window', 'app.perksService'];
app.controller('app.perksApprovalController', PerksApprovalController);
function PerksApprovalController($window, PerksService) {
/* jshint validthis:true */
var vm = this;
vm.showDetails = function (controlNo) {
$window.location = ;
$location.path('/PerksDetails/PerksView'+controlNo);
}
}
})();
In Routes.js or the place where you define the routes of your angular application add the following lines:
.when('/PerksDetails/PerksView/:controlNo', {
templateUrl: '<YOU DEFINE THE TEMPLATE>',
controller: 'PerksDetailController',
reloadOnSearch: false })
Here ":controlNo" is used to pass the value you are passing in the url from PerksApprovalController.
In PerksDetailController we get the controlNo from routeParams and pass it to your PerksService to get the details from it.
PerksDetailCtrl.js
(function () {
'use strict';
var app = angular.module('app');
PerksDetailController.$inject = ['$scope', '$http', '$q', '$window', '$routeParams', 'app.perksService'];
app.controller('app.perksDetailController', PerksDetailController);
function PerksDetailController($scope, $http, $q, $window, $routeParams, PerksService) {
var vm = this;
PerksService.getPerksItems($routeParams.controlNo).then(function (response) {
vm.perksItemDetails = response.data;
});
}
})();
Hope it Solves your problem! Thank You!
Related
Is it possible to call a function from child controller in app.run?
my sub-app facebook controller:
function faceBookController ($scope, $rootScope, faceBookService) {
// I want to call this #scope.init in app.run
$scope.init = function () {
checkLoginState();
};
function checkLoginState () {
faceBookService.init();
}
}
angular.module('app.facebook').controller('faceBookController', ['$scope', '$rootScope', 'faceBookService', faceBookController]);
app.run:
function runFunction (User, $rootScope) {
*****
$window.fbAsyncInit = function() {
FB.init({
appId : '************',
version : 'v2.5' // use graph api version 2.5
});
//Here after facebook sdk connected execute init fruntion from faceBookController.
$rootScope.init();
}
angular.module('app.run', []).run(['User', '$rootScope', runFunction]);
and main app.js file:
angular.module('app', ['ngRoute', 'app.run', 'app.facebook']);
Inside your run you can call the controller function like below
You can give an id for the div where the scope of the controller belongs,
<div id="yourcontainer" ng-app="test" ng-controller="faceBookController">
</div>
and then,
function runFunction (User, $rootScope) {
$window.fbAsyncInit = function() {
FB.init({
appId : '************',
version : 'v2.5' // use graph api version 2.5
});
var scope = ngular.element(document.getElementById('yourcontainer')).scope();
scope.init();
}
OK, I've built services before but obviously I don't actually know what makes them tick, since I can't seem to debug this ultra-simple service call:
app.js:
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope, dataService) {
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
dataService.js:
(function() {
'use strict';
angular
.module('gridApp')
.service('dataService', dataService)
dataService.$inject = [];
function dataService() {
console.log("I am the dataService and I am loaded");
var foo = 1;
function getData () {
return 2;
}
}
})();
I see this on-screen: I am Angular and I am working. so Angular is loading.
I see this in console: I am the dataService and I am loaded so the dataService is actually being loaded.
But then the console.log is:
undefined (line 8)
TypeError: dataService.getData is not a function (line 9)
What am I missing?
The previous answers are correct in that your $http injection was wrong, but you are also not attaching your service functions to the service:
function dataService() {
var dataService = this; //get a reference to the service
//attach your functions and variables to the service reference
dataService.foo = 1;
dataService.getData = function() {
return 2;
};
}
An Angular service is very simply an object class. It is also a singleton, meaning it's instantiated only once per run of your app. When the service is instantiated it is very much akin to calling the new operator on your dataService "class":
var $dataService = new dataService();
So, when you inject dataService into your controller, you are actually getting an instance, $dataService, of your dataService "class".
See this blog entry for further reading: https://tylermcginnis.com/angularjs-factory-vs-service-vs-provider-5f426cfe6b8c#.sneoo52nk
You are missing the 2nd parameter $http in the function. The named parameters and the actual parameters in function need to be the same, same order and same number. What happened before is that dataService was being assigned an $http instance and the actual dataService was not injected at all because there was no 3rd parameter to inject it into.
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope, $http, dataService) {
// ----was missing-----^
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
We have missed the second param '$http' in function. Just add the '$http' param, it should work fine
var gridApp = angular.module('gridApp', []);
gridApp.controller('mainController', ['$scope', '$http', 'dataService',
function($scope,$http, dataService) {
$scope.message = 'I am Angular and I am working.';
var init = function(){
console.log(dataService.foo);
console.log(dataService.getData());
};
init();
}]);
This is how I've been taught to set up services:
function dataService() {
var dataService = {};
var _foo = 1;
var _getData = function () { return 2; }
dataService.foo = _foo;
dataService.getData = _getData;
return dataService;
}
I believe this facilitates public/private methods/vars.
For reference, this is the full code accessing my service:
app.js:
var gridApp = angular.module('gridApp', []);
// create the controller and inject Angular's $scope
gridApp.controller('mainController', ['$scope', 'dataService', function($scope, dataService) {
// create a message to display in our view
$scope.message = 'Angular is working';
var init = function(){
getPackageData();
};
var getPackageData = function (){
return dataService.getData().then(
function successCallback(response) {
console.log(response);
},
function errorCallback(response) {
console.log(response);
}
);
};
init();
}]);
dataService.js:
(function() {
'use strict';
angular
.module('gridApp')
.service('dataService', dataService)
dataService.$inject = ['$http'];
function dataService($http) {
var dataService = {};
var _getData = function () {
return $http({
method: 'GET',
url: 'data/packages.json'
})
.then(function successCallback(response) {
return response;
},
function errorCallback(response) {
return response;
});
}
dataService.getData = _getData;
return dataService;
}
})();
Is there a way to pass info from a controller to service? I know that you should pass info from the service to the controller, but let me explain you my problem:
I have two screens (or two views) with different controller but with the same module. Let's name them: ControllerOne with ViewOne and ServiceOne AND ControllerTwo with ViewTwo and ServiceTwo.
ServiceOne makes an http request to get some json data (from a remote origin). In ControllerOne I have a function where it calls the ServiceOne to get all data and in the ViewOne I show the list of all videos fetched from the remote origin (from ControllerOne).
The code for ServiceOne is shown above:
(function() {
'use strict';
angular
.module('MyApp.MyModule')
.factory('ServiceOne', ServiceOne);
ServiceOne.$inject = ['$http', '$q'];
function ServiceOne($http, $q) {
var url = 'https://THE_LINK_I_WANT_TO_GET_DATA_FROM';
var result = [];
var service = {
getAllVideos: getAllVideos,
getVideo: getVideo
};
return service;
function getAllVideos(callback){
$http.get(url)
.success(function(data) {
result = data.result;
callback(result);
});
}
function getVideo(videoId) {
for (var i = 0; i < result.length; i++) {
if (result[i].videoId === videoId) {
return $q.when(result[i]);
}
}
return $q.when(null);
}
}
})();
The ControllerOne looks like this:
(function() {
'use strict';
angular
.module('MyApp.MyModule')
.controller('ControllerOne', ControllerOne);
ControllerOne.$inject = ['$scope', '$state', 'ServiceOne'];
function ControllerOne($scope, $state, ServiceOne) {
var vm = angular.extend(this, {
videos: [],
navigateToVideo: navigateToVideo
});
ServiceOne.getAllVideos(function(data){
vm.videos = data;
});
function navigateToVideo(videoId) {
$state.go('app.video', { videoId: videoId } );
}
}
})();
On ViewOne, everytime someone clicks on a video, I navigate them to another view (ViewTwo in my case) and a parameter is passed (a unique id).
The ControllerTwo looks like this:
(function() {
'use strict';
angular
.module('MyApp.MyModule')
.controller('ControllerTwo', ControllerTwo);
ControllerTwo.$inject = ['$scope', '$state', '$stateParams', 'ServiceOne'];
function ControllerTwo($scope, $state, $stateParams, ServiceOne) {
var vm = angular.extend(this, {
video: []
});
(function init(){
loadData();
})();
function loadData(){
var videoId = String($stateParams.videoId);
ServiceOne.getVideo(videoId)
.then(function(video) {
vm.video = video;
});
}
}
})();
In the ControllerTwo I save the parameter passed from ControllerOne, and save it on videoId. Then I call a function of ServiceOne to get the object I was looking for.
So, my question is:
Can I pass the object vm.video of the ControllerTwo to ServiceTwo, so I can use it in the future?
Thanks!
Services are MADE for sharing stuff(data and methods) across you application. So, to answer your question simply: absolutely, yes you can pass your object to your service. And, it couldn't be any easier...
ServiceOne & ServiceTwo can be accessed by ANY controller, and if you want to "pass something" to a service it's as simple as this:
ControllerOne.$inject = ['$scope', '$state', 'ServiceOne', 'ServiceTwo'];
function ControllerOne($scope, $state, ServiceOne, ServiceTwo) {
function loadData(){
var videoId = String($stateParams.videoId);
ServiceOne.getVideo(videoId)
.then(function(video) {
vm.video = video;
ServiceTwo.video = video; //bam, you're done
});
}
}
The video will persist until you restart the app.
ControllerOne.$inject = ['$scope', '$state', 'ServiceOne', 'ServiceTwo'];
function ControllerOne($scope, $state, ServiceOne, ServiceTwo) {
// now you can access it from your other controller
var videoStoredInServiceTwo = ServiceTwo.video;
}
The only thing to be aware of is timing. You might want to check that the video exists on ServiceTwo before you try to retrieve it.
if( ServiceTwo.video ) {
videoStoredInServiceTwo = ServiceTwo.video;
}
In my application, I have a service creating a new structure with two json files. So, I use $q.all to use them in a same time.
angular.module('myApp', []).factory('myService', ['$http', '$q', function ($http, $q) {
var myStructure = function () {
var firstJson = $http.get('datas/firstJson.json');
var secondJson = $http.get('datas/secondJson.json');
return $q.all([firstJson, secondJson]).then(function (values) {
var myMap = new Map();
/*
treatment on myMap
*/
return myMap.values();
});
}
return myStructure();
}]);
So, I use this service in myController by using myService.then
var myApp = angular.module('myApp');
myApp.controller('myApp', ['$scope', 'myService', function ($scope, myService) {
myService.myStructure.then(function(value){
$scope.myStructure = value;
});}]);
Finally, when I use {{myStructure}} in my HTML page, after instantiate myApp with ng-controller, the page display {} (an empty object).
Thank you in advance for your help.
Move the myMap logic inside resolve callback in the controller
Service:
angular.module('myApp', []).factory('myService', ['$http', '$q', function ($http, $q) {
var myStructure = function () {
var firstJson = $http.get('datas/firstJson.json');
var secondJson = $http.get('datas/secondJson.json');
return $q.all([firstJson, secondJson]);
}
return myStructure();
}]);
Controller:
var myApp = angular.module('myApp');
myApp.controller('myApp', ['$scope', 'myService', function ($scope, myService) {
myService.myStructure.then(function(values){
var myMap = new Map();
/*
treatment on myMap
*/
$scope.myStructure = myMap.values();
});
}]);
I try to pass object from index.html controller(signupCtrl) to connexion.html (controller:affCtrl)and display the object in the form of connexion.html using a factory, I created this plunker
This is the script.js file that contains two controllers
'use strict'
var demoApp = angular.module('demoApp', []);
demoApp.controller('signupCtrl', function($scope, $rootScope, per) {
$scope.envoie = function (user) {
per = user;
console.log(per);
window.location="connexion.html"
};
});
demoApp.controller('affCtrl', function($rootScope, per) {
$rootScope.per = per;
});
And the factory:
demoApp.factory("per",function() {
return {
"name":"",
"password":"",
}
});