Angularjs pass parameters so they are hidden - angularjs

I'd like to know how what is the best (and most secure) way to pass parameters (such as product id) between views so the user cannot see them in the url bar.
Thank you.
Stephan

You should pass them from one controller to another controller in the new view. Here is a pretty good answer on how to do that: LINK

Store them in a shared service and use them when you need them, quick sample:
app.factory("shared", function() {
var data = null;
return {
setData: function(someData) {
data = someData;
},
getData: function() {
return data;
}
}
});
And now use it!
app.controller("myCtrl", function($scope, shared) {
$scope.data = shared.getData();
});

A good way to do this is to use the Angular Service pattern.
Because the controllers are functions and the services are objects (singletons) You can have multiples services according to the differents functionnalities that you have in your app.
You should see the documentation for Angular providers here :
https://docs.angularjs.org/guide/providers

Related

Difference between using a service and a controller in Angular

Its my first first time using javascript and angular.
So Im developing a web page with angular, and I wrote a Controller like this:
/*BrandController to manage the html content of a single brand */
.controller('BrandController', [function(){
this.brand = {};
this.isSet = function(checkBrand) {
return this.origin === checkBrand;
};
this.setBrand = function(activeBrand) {
this.brand = activeBrand;
};
}])
I have some tabs of brands and when I click one, that brand is assigned with the controller.
<a href ng-click="BrandController.setBrand(brand)">
<h4>{{brand.name}}</h4></a>
And I show its content like this:
<b>Nombre</b><br>
{{BrandController.brand.name}}<br><br>
<b>Marca</b><br>
{{BrandController.brand.brand}}<br><br>
So, It works the way I wanted, but a friend told me this was not the correct way to do it. That I have to create a service, to pass the information of brand. And we got it like this:
/* BrandController to manage the html content of a single brand */
.controller('BrandController', function(BrandService, $scope){
$scope.brand = {
};
$scope.setBrand = function(brand){
$scope.brand = brand;
};
$scope.isSet = function(brand){
return $scope.brand === brand;
};
})
.service('BrandService', function(){
var brand = {};
var isSet = function(checkBrand) {
return brand === checkBrand;
};
var setBrand = function(activeBrand) {
brand = activeBrand;
};
return{
isSet: isSet,
setBrand: setBrand
};
});
This works too, as you can see is much more code, and I could not to understand why should I create a service instead.
So, If you can explain in my example what is the best way to do it and why I would be very grateful.
Thank you.
There are some situation while service are really usefull.
with a service you can abstract the logic to read data keeping your controller standard. In case your data structure change you can change the logic in the service without touching the controller(and potentially the view).
The controller is responsible for binding data to the view and should not care about how the data are received or structurated.
Service are also singleton so you can store data cross controller or between controller and directives.
Most used application of those concepts are data services. here you can find a good documentation explaining the best practice and some logical advantages.
hope this helps

pass data from view1 to view2 using local storage in angularjs

I am new to angular and I want to pass data from one page to another page using local storage.I have tried a lot but unable to find the correct answer
Use factory like below.
angular
.module('xx.services', [])
.factory('xxStorage', ['$window', function($window) {
return {
set: function(_key, _value) {
$window.localStorage[_key] = _value;
},
get: function(_key) {
return $window.localStorage[_key];
}
};
}])
You can use set function to save data in the first page, and then reuse using get function in the other page.
The best way is to use library which already wrapped localStorage functionality in angular area. So there are few such popular solutions like: ngStorage and angular-local-storage. I prefer first one.
Git page, here you can find all information about installing, and using.
Just for example here is sample
var app = angular.module('app', ['ngStorage'])
.config(['$localStorageProvider',
function ($localStorageProvider) {
$localStorageProvider.get('MyKey');
$localStorageProvider.set('MyKey', { k: 'value' });
}]);

how to store some data in angularJs for later use?

I have a simple Query. How can I store some data or value in angularJs for the later use? Let me be more clear: I want to store a value from one controller and use it in other controller?
you should use angular service to achieve this. note that angular service is singleton which can be injected into controllers. a quick prototype to show the basic:
angular.module('myApp', []).factory('myService', function () {
var o = {x:1, y:2};
return {
getO: getO,
setO: setO
};
function getO() {
return o;
}
function setO(x, y) {
o.x = x;
o.y = y;
}
});
angular.module('myApp').controller('MyCtrlA', function ($scope, myService) {
myService.setO(3, 4);
});
angular.module('myApp').controller('MyCtrlB', function ($scope, myService) {
var o = myService.getO(); // {x:3, y:4}
});
Sounds like a "service" in Angular terminology. For persisting data inside the service you can use wide variety of implementations from local storage to cloud json backend like firebase.
There is a $cacheFactory if you do not need to refresh the page it will do the trick https://docs.angularjs.org/api/ng/service/$cacheFactory
So you can easily put and get stuffs from the cache wherever you want and whenever you need

AngularJS dependency injection swap implementation

I'm still learning AngularJS, and have a question regarding their flavor of dependency injection. For example purposes, say I have a DataProcessor service which has a processData method that takes in a uri parameter and it needs to read that data (which may be xml, json, etc.) and then perform some actions on it. The DataProcessor constructor takes in an implementation of a DataReader interface that knows how to read a certain file type. Here are some example services of what I'm talking about:
// implementations of the DataReader interface
myApp.service('XmlDataReader', function() {
this.readData = function(uri) {
// read xml data from uri
}
}]);
myApp.service('JsonDataReader', function() {
this.readData = function(uri) {
// read json data from uri
}
}]);
// data processing service that takes in an implementation of a DataReader
myApp.service('DataProcessor', ['DataReader', function(DataReader) {
this.processData = function(uri) {
var readData = DataReader.readData(uri);
// process data and return it
}
}]);
From a typical dependency injection perspective, a specific type of DataReader could be passed into the DataProcessor and used like so:
var dataProcessor = new DataProcessor(new JsonDataReader());
var processedData = dataProcessor.processData('dataz.json');
What is the AngularJS way of doing this?
Do something like this:
myApp.service('DataProcessor', ['$injector', 'valueRecipeOfTheServicename', function($injector, valueRecipeOfTheServicename) {
this.processData = function(uri) {
var service = $injector.get(valueRecipeOfTheServicename);
// process data and return it
}
}]);
$injetcor.get() retrieves a service
Based on Noypi Gilas answer, I am initiating the controller with the name of the service and retrieving it via $injetcor.get():
myApp.service('DataProcessor', ['$injector', function($injector) {
var service;
$scope.init = function (serviceName) {
service = $injector.get(serviceName);
}
this.processData = function(uri) {
// use the service ...
}
}]);
Because of the way DI works - you shouldn't have to create instances of your services, ever really. What you do is you inject the service(s) you need into your controller and it should just work. In the case above, your controller might be defined to be:
var app = angular.module('App', ['DataProcessor']);
function MyController($scope, DataProcessor) {
var uri = '';
DataProcessor.processData(uri);
}
The only other thing you need to do here is make sure that "App" is the name you specify in the "ng-app" directive and make sure that your page includes the JS files with "DataProcessor" before you include the angular app module (technically these could even be defined in the same file). Hope this helps!
Edit
By the way, if you need to minify - the following is how you would define the controller:
var app = angular.module('App', ['DataProcessor']);
// if you need to minify:
var MyController = ['$scope', 'DataProcessor',
function($scope, DataProcessor) {
var uri = '';
DataProcessor.processData(uri);
}
];
Additional Suggestions
My understanding of a service at the present time is that is is used to shared data or code between controllers. If this data processing is specific to that controller you might consider just moving the "ProcessData" implementation directly into your controller. Sometimes changes like this can be simpler than processing the data in a service. If you do process the data in the service you might still want to write that data back to the scope. In this case, you can pass $scope as a parameter into the service routine. Since I don't know too much about your use case, just take these suggestions with a grain of salt. Good luck!

Grouping back-end APIs

While using AngularJS's $http service I've found hard to manage all urls to backend - they're spread around controller's code. Sometimes they're even duplicated. Mostly all of them are in form of $http.get('/api/something').then(...).
To put all of them into different services sounds quite unreasonable: it is just one line of code with may be just small modifications (like adding header etc).
Other solution could be putting them into constants, but in this case I would still use $http.get(APIURLs.SomeURL) that looks like little bit verbose...
So the question is: what is the best way to manage URLs to back-end?
Currently I came up with idea of grouping them into servicies and expose them as calls to $http. Here is my solution:
http://plnkr.co/edit/VjqXHBV54bmjKCuGJ4qX?p=preview
Service:
.factory('AdminAPI', function($http) {
var apiMap = {
'DeleteAuth': {url:'/api/oauth/delete',method:'PUT'},
'GetInvalidUser': {url:'/api/users/invalid',method:'GET'},
'CreateItem': {url:'/api/items/create',method:'POST'}
};
var api = {};
var prepareCall = function(config) {
return function(params) {
var requestConfig = angular.copy(config);
if (config.method=='GET')
requestConfig.params = params;
else
requestConfig.data = params;
return $http(requestConfig);
};
};
for(var name in apiMap)
api[name] = prepareCall(apiMap[name]);
return api;
});
And in controllers I do something like:
AdminAPI.DeleteAuth({data:123}).then(function(result) {
//
});
In this case I have some abstraction (do not have to inject $http into controller), so unit-tests become little bit easier (I do not have to use $httpBackend service, just mock my service calls).
Make use of angular Module.constant:
Move reusable settings to single object;
Define angular module wrapping this object:
angular.module('myApp.constants', []).constant('config', {
ROUTES: {
home: '/home.html',
about: '/about.html'
}
});
load myApp.constants module into application with all the others:
angular.module('myApp', [
'myApp.constants',
'myApp.services',
'myApp.controllers',
'myApp.filters',
'myApp.directives'
]);
After that you can inject config dependency and access defined hash.
Good question. My suggested approach is to put the constants in a constantdeclaration like this:
angular.module('fooApp').constant('config', {
api: {
baseUrl: 'http://api.example.com/api',
key: 'SECRET_API_KEY',
}
});
And you could implement a httpResourceFactory that is responsible for creating $http or $resource references that points to different endpoints using the constants defined in config.
This could be implemented in a service.
Then all API endpoint definitions can be put into a single service.
angular.module('fooApp').factory('dataService', ['httpResourceFactory', function(httpResourceFactory) {
var PUBLIC_API = {};
PUBLIC_API.Orders = httpResourceFactory('/orders/:id');
PUBLIC_API.Users = httpResourceFactory('/some-url/users/:id');
return PUBLIC_API;
}]);
Then in your controller you may inject dataService and do stuff like this:
$scope.users = dataService.Users.query();
Hope this clarified it. I'm in a hurry, so ask more concrete and I will provide more examples later on.

Resources