I am trying to pass data from one page to another using AngularJs service but whatever value I set in the variables in the service on one page, it is lost on redirection. Is there any particular way to perform the redirection? Below is the flow of my code
//Created a service to pass data
angular.module('Test').service('TestService', function() {
var new_data;
this.addData = function(page_data) {
new_data = page_data;
}
this.getData = function(){
return new_data;
}
});
//Code in controller A:
TestService.addData(data);
$window.location.href = "/static/html/buyer-cart-confirmation.html"
//Code in controller B:
data = TestService.getData();
No data is received in controller B. Can somebody please help me with this.
Thank you!
You can use session storage to serialize / deserialize data across different instances of angular within the same session (tab), and you can use local storage to do the same thing across sessions, (new tab). Here is the code for both:
Session Storage
class SessionStorageService
setStorage:(key, value) ->
json = if value? then JSON.stringify value else null
sessionStorage.setItem key, json
getStorage:(key)->
JSON.parse sessionStorage.getItem key
pageData1:(value=null) ->
#accessor 'pageData1', value
pageData2:(value=null) ->
#accessor 'pageData2', value
# more data values defined here
accessor:(name, value)->
return #getStorage name unless value?
#setStorage name, value
angular
.module 'app.Services'
.service 'sessionStorageService', SessionStorageService
Local Storage Service
class LocalStorageService
setStorage:(key, value) ->
json = if value? then JSON.stringify value else null
localStorage.setItem key, json
getStorage:(key)->
JSON.parse localStorage.getItem key
clear: ->
#setStorage(key, null) for key of localStorage
pageData1:(value=null) ->
#accessor 'pageData1', value
pageData2:(value=null) ->
#accessor 'pageData2', value
# more data values defined here
accessor:(name, value)->
return #getStorage name unless value?
#setStorage name, value
angular
.module 'app.Services'
.service 'localStorageService', LocalStorageService
With that said, you need to ask yourself why you are redirecting to a different page with any expectation that your state will somehow be preserved?
Angular is typically used for Single Page Applications that use routing frameworks like ui-router to manage state transformations, rather than the old-school, click-and-refresh-the-page model.
In other words, you should not redirect unless you intend on starting a brand new Angular application.
I think your logic is wrong, and since you don't provide a Plunker I can't test it at the moment. I think you should go with smth like:
angular.module('Test').service('TestService', function() {
this.addData = function(page_data) {
this.new_data = page_data;
};
return this;
});
and then you access your data like this:
TestService.new_data
I think it will work like this.
Related
I am creating a web application on some courses in which I need to save a field (username) throughout the session of the user that is logged in, then in another part when the user finishes the course and clicks on the "Accept" button, the progress is saved in a field in the database.
If I ask the user previously to introduce the field and click on "Accept", I pick it up and I treat it in the function of the ModifyProgress controller, this does work for me, but I need not to ask that field from the user. That is, only by entering your name once in the login, you can already treat that variable throughout the application.
I tried a typical global variable at the beginning of the controller file, and I assign it to the field (GlobalUserName = $scope.username) but it is only stored in the Login function. When I try to use in other function I get a "undefined" alert in the chrome console (f12).
var app = angular.module('gestionUsuarioCurso');
app.controller('usuariosCursoController',
function($scope,$http,usuariosCursoService) {
gestionUsuarioCurso = this;
gestionUsuarioCurso.progresoUsuario;
gestionUsuarioCurso.usuario;
gestionUsuarioCurso.curso;
gestionUsuarioCurso.usuarios = [];
gestionUsuarioCurso.status;
GlobalUsername;
this.progresoUsuario = 0;
this.selectProgreso = function (){
return this.progresoUsuario;
};
$scope.LoginUsuario = function(){
usuariosCursoService.loginUser(
$scope.userName,$scope.password).then(function(usuario){
Globalusername = $scope.userName;
gestionUsuarioCurso.usuario = usuario;
console.log(GlobalUsername); //This shows it correctly
.......
With the $scope.userName I get the username and I can treat it in that function, but if I want to use it now in this other function of ModifyProgress, it appears to me by the debug console (f12 in chrome) undefined that field.
The showUser method (within ModifyProgress) tries to find a user in the bbdd with the username field, in this case the user passes it to them by hand.
$scope.ModifyProgress = function(FinishedCourse){
//console.log(GlobalUsername); //Undefined on console
usuariosCursoService.showUser(GlobalUsername).then(function(usuario) {
//console.log(GlobalUsername); //Undefined on console
gestionUsuarioCurso.usuario = usuario;
.........
I would like the variable GlobalUsername to "travel" with the value obtained on the LoginUser function to another functions with that value, and so that the value can go through webpages.
Use $rootScope instead of $scope for global variables!
$rootScope.GlobalUsername = 'Your name!!';
Read More about $rootScope
The proper way would be to create a new service.
Services are singletons and passed to your controller by reference.
So you could inject it int your first controller to store the value and inject in your other controller to retrieve this value.
https://docs.angularjs.org/guide/services
You could use $rootScope in order to have it available anywhere but it's not recommended.
See https://docs.angularjs.org/guide/scope for more details on what scopes are made for.
I have an angular model named rows.
I have a piece of code that tries to fetch data from local storage using LocalForage and set the local data to the rows model.
Apparently, it seems like, by the time the local storage call back for get item executes, the $scope.rows model goes out of scope.
Is there a way, i can achieve this, that is set the value from local storage to the rows model?
localforage.getItem(localBlogKey, function (err, readValue)
{
if (readValue !== null && readValue !== undefined)
{
var localdata = readValue.data;
$scope.rows = angular.fromJson(localData);
}
});
Since this piece of code runs asynchronously, the $scope.rows goes out of scope? Is there a sunchronous way to pull data from localforage?
This is achieved using the ngStorage Module.
Import the ngStorage module and then access the localstorage item with the key as below
localstorage.myKey = "myValue";
This is Synchronous and hence my issue is resolved.
I am trying to pass data between pages in the checkout process of an app but it's not working the way it should. I have done some reading and most people recommend using a service, but the only issue is that when the page is refreshed (user clicks refresh or comes back at a later time) all the data from the service disappears. This makes sense since the data in a service is not meant to be persistent but it is causing a problem.
So the question is: how can I pass data between pages in angularJS and still keep the data that was passed after a page refresh?
Here is my code so far (with my attempt at using query strings):
.service('checkoutService',
function checkoutService($location, Address, $routeParams, TicketGroup) {
var ticket_quantity = 0;
var ticket_group = {};
var selected_address = {};
this.loadInformation = function() {
if(!ticket_quantity && $routeParams.ticket_quantity)
ticket_quantity = $routeParams.ticket_quantity;
if(!ticket_group && $routeParams.ticket_group_id)
ticket_group = TicketGroup.get({id: $routeParams.ticket_group_id});
if(!selected_address && $routeParams.address_id)
selected_address = Address.get({id: $routeParams.address_id});
}
this.setTicketQuantity = function(quantity) {
ticket_quantity = quantity;
$location.path().search({ticket_quantity: quantity});
}
this.getTicketQuantity = function() {
return ticket_quantity;
}
this.setTicketGroup = function(object) {
ticket_group = object;
$routeParams.ticket_group = object.id;
}
this.getTicketGroup = function() {
return ticket_group;
}
this.setSelectedAddress = function(object) {
selected_address = object;
$routeParams.address_id = object.id;
}
this.getSelectedAddress = function() {
return selected_address;
}
});
There are several options to do this,
For smaller data sets you could use the $cookieStore, for data that is under 4k
Another option, especially with large data sets, would be to use Local Storage and then retrieve the data on page load/reload.
if it is only a very small amount of data, or data that is used through out multiple page you could use $rootscope, but this is not the best option as it just like polluting the global name space.
The last option, depending on how the data is retrieved, a service could be implemented, that is basically a singleton that can be passed to various angular scope.
Note: only the first two are persistent.
In your case I think that using local storage or the cookiestore will be you best options. You are trying to use a service, which would be appropriate if you did not want it to be persistent (leaving the page or a page refresh). Services are singletons that being managed by angular, when injected you will get a reference to the same object in each injection. However, when returning to the page this singleton will need to be re initialized, thus losing all previous data. The only way to make make a service persistent would be to load the data from a database, a local file, or noSQL from elsewhere. However, I do not think this is really what you are after.
If you are interested in pursuing the local storage implementation then look into these modules angular-local-storage, ngStorage or this answer
If you want to use the cookiestore look into this answer
You can use Session/LocalStorage. Or a browser db like pounchdb.
Seesion storage: store session data;
LocalStorage: store data not just session scope
pounchdb : offline db
UPDATE : find my answer here
A little clarity on getting key values using AngularFire v2?
I looked for many sources before asking a simple question but Im just sarting with firebase and I can't manage to use the data the way I want. What I need, is to retrieve two int in my controller (how much "yes" and how much "no" linked to a question.
the data model is the following
question/id/(text, yes, no)
I have a service where I call my data using an id
app.service('QuestionService', function($firebase,$q) {
var _this = this;
//initialize Firebase
var ref = new Firebase('https://basename.firebaseio.com/question');
this.get = function(nb){
var QuestionObject = ref.child(nb);
return $firebase(QuestionObject);
};
return this;
});
I have a controller function where I call some data using a random id
$scope.pickQuestion = function(){
var randomnumber = Math.ceil(Math.random() * 3);
$scope.message = QuestionService.get(randomnumber);
};
and then it works great so I can have something like
{{message.yes}} or {{message.no}} and get the corresponding integer.
My issue, what I want to do, is to pass this "message.no" value to my controller. I don't know what to do. I can't manage to get the value directly inside the controller (it works only inside the view) and I can't manage to pass the value to my controller from the view. I tried a
ng-init="functionName({{message.yes}}, {{message.no}})"
but it return an error into the console. (however the source a displayed correctly)
Does someone could guide me into the right direction?
Thanks
I have a json endpoint that returns a list of objects. The first view is a list with just some basic info but if you select an item I want to show more details. Should I just construct and object in my factory and have another method to get the details? so
getItems() // returns list data
getItem(id)// goes through the object already retrieved and returns just the data?
I don't want to hit the server again for each item but I'm not sure of the best way to do this in Angular. It doesn't appear the Model is made for this in Angular.
Also, assuming Item has additional information that I may need to make another server request. What's the best way to store this locally so if I already fetches these details once I don't need to get it again?
If you want to exchange data between 2 controllers, you can use a provider
App.provider('Data', function() {
//Properties declaration
this.info = '';
//Setters
this.setInfo = function(info) {
this.info = info;
};
//Getters
this.getInfo = function() {
return this.info;
};
controller 1
App.controller(
'controller1',
['$scope', 'Data',
function($scope, Data) { Data.setInfo('here you put what you want') }]);
controller which get back information
App.controller(
'controller2',
['$scope', 'Data',
function($scope, Data) { Data.getInfo() }]);
More likely, you'll want to use either a factory or a service:
https://docs.angularjs.org/api/auto/service/$provide#factory
https://docs.angularjs.org/api/auto/service/$provide#service
In both cases, you provide a function which Angular will call once and store the return reference, then provide that reference to any controller or other Angular-managed object that requests it. The difference between a factory and service is that a service function is expected to be a constructor function (it's called using the "new" keyword) whereas a factory is a just invoked as a regular function.