app.controller('ItemDetailsCtrl', function($scope,FavoriteService) {
var parameter = $scope.Diamoni.Favorites;
});
app.service("FavoriteService",[function(){
this.fav = 0;
}]);
I would like to pass the variable parameter from ItemDetailsCtrl controller to FavoriteService, So this.fav=0; become this.fav=parameter Any suggestions? Thanks in advance.
Dont use $rootScope, instead use a function to set the params
In your service
var self = this;
this.setParam = function(param){
self.fav = param
}
In your controller
FavouriteService.setParam(parameter)
I think the cleanest way will be to expose your fav variable through get/set methods.
app.controller('ItemDetailsCtrl', function($scope, FavoriteService) {
var parameter = $scope.Diamoni.Favorites;
FavoriteService.setFav(parameter);
console.log(FavoriteService.getFav()); // will be the proper value
});
app.service("FavoriteService",[function(){
var fav = 0;
this.setFav = setFav;
this.getFav = getFav;
function setFav(favValue) {
fav = favValue;
}
function getFav() {
return fav;
}
}]);
try this out:
app.controller('ItemDetailsCtrl', function($scope,FavoriteService) {
var parameter = $scope.Diamoni.Favorites;
FavoriteService.setParam(parameter);
});
app.service("FavoriteService",[function(){
var service = this;
service.setParam = function(parameter) {
service.fav = parameter;
};
}]);
I added a method to the service to set the fav variable.
its easy to implement this kind of logic using factory instead of service. if you want i can send you the factory code snippet
EDIT
using factory:
app.controller('ItemDetailsCtrl', function($scope,FavoriteService) {
var parameter = $scope.Diamoni.Favorites;
FavoriteService.setParam(parameter);
});
app.factory('FavoriteService', ['', function(){
var service = {}
service.setParam = function(parameter) {
service.fav = parameter;
};
return service;
}])
}]);
Here's a neat data sharing service example, where we store different data using set and get methods. Remember to store the values in an object or you can get some strange results sometimes.
Service:
graphs.service('graphsData', [function() {
var graphs = this;
var data = {
all: null,
list: null,
single: null
};
graphs.set = function(k, v) {
data[k] = v;
};
graphs.update = function(k, s, v) {
data[k][s] = v;
};
graphs.get = function(k, v) {
return data;
};
}]);
From your controller:
// Stores the this.fav variable as myFavoriteValue (data.myFavoriteValue)
graphsData.set('myFavoriteValue', this.fav);
To get the value simply call the get function of the service:
graphsData.get().myFavoriteValue;
Related
I'm using a service in order to pass data between different instances of an AngularJS controller. I know that this is not the best way to do it but it's the way that fits my case. The problem is that I cannot get data out of that Service.
var app = angular.module('MovieApp', ['ngResource']);
app.factory('factMovies', function($resource) { //this returns some movies from MongoDB
return $resource('/movies');
});
app.service('SnapshotService', function(factMovies) {
//this is used to pass data to different instances of the same controller
//omitted getters/setters
this.snapshots = [];
this.init = function() {
var ctrl = this;
var resp = factMovies.query({}, function() {
if (resp.error) {
console.log(resp.error)
} else {
tempDataset = []
//do stuff and put the results in tempDataset
ctrl.snapshots.push(tempDataset);
console.log(tempDataset); //prints fine
return tempDataset;
}
});
};
});
app.controller('TileController', function(SnapshotService) {
this.dataset = [];
this.filters = [];
this.init = function() {
var ctrl = this;
var data = SnapshotService.init(function() {
console.log(ctrl.data); //doesn't even get to the callback function
});
};
});
I really can't figure out what I'm doing wrong..
SnapshotService.init() doesn't take any parameters - meaning the anonymous function you pass in with the SnapshotService.init() call in TileController does nothing.
What you need to do is add the parameter to the init function definition and then call it in the code:
app.service('SnapshotService', function(factMovies) {
//this is used to pass data to different instances of the same controller
//omitted getters/setters
this.snapshots = [];
this.init = function(cb) {
var ctrl = this;
var resp = factMovies.query({}, function() {
if (resp.error) {
console.log(resp.error)
} else {
tempDataset = []
//do stuff and put the results in tempDataset
ctrl.snapshots.push(tempDataset);
console.log(tempDataset); //prints fine
cb(ctrl.snapshots);
}
});
};
});
I am trying to pass a JSON string value that is stored in one controller to another. I am using a custom service to pass the data, but it doesn't seem to be passing the value.
The First controller where the JSON string value is stored:
filmApp.controller('SearchController',['$scope', '$http','$log','sharedService',function($scope,$http,$log,sharedService){
$scope.results = {
values: []
};
var vm = this;
vm.querySearch = querySearch;
vm.searchTextChange = searchTextChange;
vm.selectedItemChange = selectedItemChange;
function querySearch(query) {
return $http.get('https://api.themoviedb.org/3/search/movie?include_adult=false&page=1&primary_release_year=2017', {
params: {
'query': query,
'api_key': apiKey
}
}).then(function(response) {
var data = response.data.results.filter(function(obj) {
return obj.original_title.toLowerCase().indexOf(query) != -1;
})
return data;
for (var i = 0; i < data.results.length; i++) {
$scope.results.values.push({title: data.results[i].original_title});
// $log.info($scope.results.values);
}
return $scope.results.values;
})
};
function searchTextChange(text) {
// $log.info('Search Text changed to ' + text);
}
function selectedItemChange(item) {
$scope.value = JSON.stringify(item);
return sharedService.data($scope.value);
}
}]);
The custom Angular service - The value is received here:
filmApp.service('sharedService',function($log){
vm = this;
var value = [];
vm.data = function(value){
$log.info("getValue: " + value); // received value in log
return value;
}
});
The Second controller that wants to receive the JSON value from the First controller:
filmApp.controller('singleFilmController',['$scope', '$http','$log','sharedService',function($scope,$http,$log,sharedService){
var value = sharedService.data(value);
$log.info("Data: " + value);
}]);
The value is received in the service but the second controller can't seem to access it. Not sure why it is happening as I'm returning the value from the data() method from the service. Also, the selectedItemChange method is used by the md-autocomplete directive.
A good approach would be using a Factory/Service. take a look at this: Share data between AngularJS controllers
Technically, you can resolve this by simply changing your service definition to
(function () {
'use strict';
SharedService.$inject = ['$log'];
function SharedService($log) {
var service = this;
var value = [];
service.data = function (value) {
$log.info("getValue: " + value); // received value in log
service.value = value;
return service.value;
};
});
filmApp.service('SharedService', SharedService);
}());
But it is a very poor practice to inject $http directly into your controllers. Instead, you should have a search service that performs the queries and handle the caching of results in that service.
Here is what that would like
(function () {
'use strict';
search.$inject = ['$q', '$http'];
function search($q, $http) {
var cachedSearches = {};
var lastSearch;
return {
getLastSearch: function() {
return lastSearch;
},
get: function (query) {
var normalizedQuery = query && query.toLowerCase();
if (cachedSearches[normalizedQuery]) {
lastSearch = cachedSearches[normalizedQuery];
return $q.when(lastSearch);
}
return $http.get('https://api.themoviedb.org/3/search/movie?' +
'include_adult=false&page=1&primary_release_year=2017', {
params: {
query: query,
api_key: apiKey
}
}).then(function (response) {
var results = response.data.results.filter(function (result) {
return result.original_title.toLowerCase().indexOf(normalizedQuery) !== -1;
}).map(function (result) {
return result.original_title;
});
cachedSearches[normalizedQuery] = results;
lastSearch = results;
return results;
}
});
}
}
filmApp.factory('search', search);
SomeController.$inject = ['$scope', 'search'];
function SomeController($scope, search) {
$scope.results = [];
$scope.selectedItemChange = function (item) {
$scope.value = JSON.stringify(item);
return search.get($scope.value).then(function (results) {
$scope.results = results;
});
}
}
filmApp.controller('SomeController', SomeController);
}());
It is worth noting that a fully fledged solution would likely work a little differently. Namely it would likely incorporate ui-router making use of resolves to load the details based on the selected list item or, it could equally well be a hierarchy of element directives employing databinding to share a common object (nothing wrong with leveraging two-way-binding here).
It is also worth noting that if I were using a transpiler, such as TypeScript or Babel, the example code above would be much more succinct and readable.
I'm pretty new to AngularJS but I'm pretty sure all you are doing is two distinct function calls. The first controller passes in the proper value, the second one then overwrites that with either null or undefined
I usually use events that I manually fire and catch on my controllers. To fire to sibling controllers, use $rootScope.$emit()
In the other controller then, you would catch this event using a $rootscope.$on() call
This article helped me a decent amount when I was working on this in a project.
I want to create a factory for routing purposes. I want to encapsulate this in a factory because I want to exchange info from one page to another. I don't know if this is the best practice. Please tell me if there are other better ways.
This is my controller:
angular.module('app.core')
.controller('mainCtrl', ['ShowService', 'ChangeViews', function(ShowService, ChangeViews){
var vm = this;
vm.namespaces = [];
vm.servers = [];
vm.p4path = '';
vm.gitpckname = '';
vm.server = '';
vm.ns = '';
ShowService.getNamespaces().then(function(response){
var data = angular.fromJson(response.data);
angular.forEach(data.namespaces, function(value){
vm.namespaces.push(value);
vm.initNamespaceSelVal = vm.namespaces[0];
vm.ns = vm.namespaces[0];
});
});
ShowService.getServers().then(function(response){
var data = angular.fromJson(response.data);
angular.forEach(data.servers, function(value){
vm.servers.push(value);
vm.initServerSelVal = vm.servers[0];
vm.server = vm.servers[0];
});
});
vm.doClick = function(value){
if(value){
var body = {};
body['server'] = vm.server;
body['p4path'] = vm.p4path;
body['packagename'] = vm.gitpckname;
body['namespace'] = vm.ns;
ShowService.getBraches(body).then(function(response){
console.log(response);
//$location.path('/hidden');
//ChangeViews.changeView('/hidden');
});
};
};
}]);
In the above code, I injected two custom made factories into controller. The "ShowService" works properly but the "ChangeViews" returns some errors.
Using $location service inside the controller(the commented line) works.
The factory code is:
angular
.module('app.services')
.constant('BASE_URL', 'http://localhost:8066')
.factory('ShowService', dataService)
.factory('ChangeViews', changeViews);
function dataService($http, BASE_URL){.....}
function changeViews($location, view){
var data = {
'changeView': changeView,
};
function changeView(view){
return $location.path(view);
};
return data;
}
The path to the html template is routed.
The error I'm receiving when injecting the ChangeViews factory is:
"Error: [$injector:unpr] http://errors.angularjs.org/1.5.5/$injector/unpr?p0=viewProvider%20%3C-%20view%20%3C-%20ChangeViews
What I'm missing?
Thank you
The problem is that you don't have injectable service named view, hence the unknown provider error.
Remove view from changeViews parameters list:
function changeViews($location) {
var data = {
changeView: changeView
};
function changeView(view) {
return $location.path(view);
};
return data;
}
I need a service that provide me a scope or dynamic var , so I move on to other controllers.
I did a test on JSBin and is not working .
https://jsbin.com/semozuceka/edit?html,js,console,output
angular.module('app', [])
.controller('control1', function($scope, shared) {
shared.set('teste', {
testecontroller1: "Apenas um teste"
});
$scope.teste = shared.get();
$scope.teste2 = shared.get();
})
.controller('control2', function($scope, shared) {
$scope.teste = shared.get('teste');
shared.set('teste2', {
testecontroller2: "Apenas um teste"
});
$scope.teste2 = shared.get('teste2');
})
.service('shared', function($scope) {
$scope.data = {};
this.set = function(key, obj) {
$scope.data[key] = obj;
};
this.get = function(key) {
return $scope.data[key];
};
});
I would go for a factory service, since there is no need to create a custom one. Given the functionality of your controllers, I've created a simple factory, like so:
.factory('shared', function() {
var shared;
var data = {};
shared = {
set: setFunc,
get: getFunc
};
return shared;
function setFunc(key, input){
data[key] = input;
}
function getFunc(key){
if(key)
return data[key];
else return data;
}
})
The only part that might need clarification is the getFunc. In control1, you want to get the data object without specifying any properties. However, in control2 you do specify, which led to the conditional if(key). So to sum up, this function checks whether there is a passed attribute parameter and returns the appropriate data.
Here is a working plunker.
You can read more about the different Angular providers and the comparison between them in the official documentation.
Enjoy!
Do not try to use $scope, because it'll try to use the scopeProvider. You cannot inject it into a service. Also, the input for a service is an array (which contains a function), not just a function.
Having said that, you don't really need the scope at all, if you keep track of your variables inside your service.
.service('shared', [function() {
var data = {};
return {
set: function(v, val) {
data[v] = val;
},
get: function(v) {
return (v)? data[v]: data;
}
};
}]);
JSbin
I'm trying to make it so that I can just add "requestCounter" to any controller and get a value that is constantly updated with the number of requests. The interceptor code is working, however the value provided by injecting requestCounter is always {count: 0}. What am I not understanding!
angular.module('theApp')
.provider('requestCounter', function ($httpProvider) {
this.$get = function () {
var activeRequests = 0;
var obj = {count: activeRequests};
$httpProvider.defaults.transformRequest.push(function(data) {
activeRequests++;
return data;
});
$httpProvider.defaults.transformResponse.push(function(data) {
activeRequests--;
return data;
});
return obj;
};
});
the controller
angular.module('theApp')
.controller('PurchaseCtrl', function ($scope, requestCounter) {
$scope.requests = requestCounter;
});
the markup
<h1>There are {{requests.count}} requests loading</h1>
In the beginning you are assigning a primitive value of activeRequests = 0 to your obj, so they are not linked to each other. You can try with:
var activeRequests = {number: 0};
var obj = {count: activeRequests};
Then you can have your counted number in obj.count.number