Not able to use cache properly in Angular JS - javascript

I have the following code snippet in my angular js web application. Intention is to use cache in controller to make the app faster.
I have defined the following cache factory in my services.js file which is to be utilized by several controllers in my app:
appServices.factory('AppCache', ['$cacheFactory', function($cacheFactory){
return $cacheFactory('app-cache');
}]);
Now I have the following code in one of my controllers:
appControllers.controller('pageController', ['$scope', 'AppCache', 'AnotherService',
function pageController($scope, AppCache, AnotherService) {
$scope.init = function () {
if (angular.isUndefined(AppCache.get('d')))
{
AnotherService.get({},
function success(successResponse) {
$scope.data = successResponse.response.r;
AppCache.put('d', $scope.data);
},
function error(errorResponse) {
console.log("Error:" + JSON.stringify(errorResponse));
}
);
}
else
$scope.data = AppCache.get('d');
}
}
The problem is I am not able to save or retrieve any data in / from the cache. My page becomes blank when I use the above code as no data is retrieved.
Please help me understand my mistake.

You named your cache 'app-cache', and you try to access it by 'd'. In the controller, just replace the 'd' with 'app-cache', it should work:
appControllers.controller('pageController', ['$scope', 'AppCache', 'AnotherService',
function pageController($scope, AppCache, AnotherService) {
$scope.init = function () {
if (angular.isUndefined(AppCache.get('app-cache')))
{
AnotherService.get({},
function success(successResponse) {
$scope.data = successResponse.response.r;
AppCache.put('app-cache', $scope.data);
},
function error(errorResponse) {
console.log("Error:" + JSON.stringify(errorResponse));
}
);
}
else
$scope.data = AppCache.get('app-cache');
}

Related

How to store data in angularjs application?

Hi I am developing my first Angularjs application. I want to save data in Angularjs application for later use(I have used localstorage in jquery before).
For example, I will make ajax call and i will get some data, Lets say below example,
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function (response) {
alert(response.data);
another example, After succesfull login i will get some ID in response and i want to preserve this data all over the application. This ID i may use in all subsequent ajax calls.
I will get some data in response and i want to make use that data in other controllers as well. Is there any way i can do this? any help would be appreciated. Thank you.
you can store it in factory like below,
After your Ajax call
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function (response) {
alert(response.data)
SomeFactory.setData(response.data);
};
SomeFactory
(function () {
'use strict';
angular
.module('app.myApp')
.factory('SomeFactory', SomeFactory);
SomeFactory.$inject = [];
function SomeFactory() {
var someData;
var factory = {
setData: setData,
getData: getData
};
function setData(data) {
someData = data;
}
function getData() {
return someData;
}
return factory;
}
})();
In your Controllers
inject your factory to your controller and then getdata
(function () {
'use strict';
angular
.module('app.login')
.controller('LoginController', LoginController);
LoginController.$inject = ['SomeFactory'];
function LoginController(SomeFactory) {
var vm = this;
vm.someVariable = SomeFactory.getData();
console.log(vm.someVariable); // logs your data
}
})();
Sharing data between controllers can be achieved with the following options :
Factory
Service
Then you can inject the service across the controllers and use the data whenever you need.
app.service('myService', function($http) {
this.getJSON = function() {
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function(response) {
return response.data;
});
};
});
In Controller:
app.controller('myController', function($scope, myService) {
myService.getJSON().then(function(data) {
$scope.myData = data;
console.log(data);
});
});
DEMO
Use Service to store the data and get the data in another controller later on.
When you inject a Service, it's the same service in every controller - so you can access the properties and methods in that service all over.
https://docs.angularjs.org/guide/services
Example:
.service('YourService', function(){
var YourService = {};
YourService.yourvar = '';
return YourService;
})
.controller('controller1', function($scope, YourService){
YourService.yourvar = 'blah';
})
.controller('controller2', function($scope, YourService){
$scope.currentYourVar = YourService.yourvar;
})

How to structure creating/updating data in Angular project with Firebase

I wonder how to structure the actual push and update methods within a Angular controller when storing to Firebase. For now I think there is lots of duplicated code and bad structure. It looks something like this:
app.controller( "myController", [ "$scope", "$routeParams", function( $scope, $routeParams ) {
$scope.id = $routeParams.id;
$scope.save = function() {
if( $scope.id ) {
// Update
}
else {
// Save
}
}
} ] );
The only difference between update and save is the methods used to store data with Firebase (push/update). Otherwise the object stored is pretty much the same and the callback is handled the same way. This gives a lot of duplicated code. How would I structure this in a good way to prevent duplicated code?
Use AngularFire.
AngularFire is the officially supported Firebase bindings for AngularJS. It has services to help with synchronized collections and authentication.
What AngularFire can really help you with here is injecting a synchronized collection to a controller via the resolve object in the router.
angular.module('app', ['firebase', 'ngRoute'])
.config(ApplicationConfig)
.constant('FirebaseUrl', '<my-firebase-app')
.service('rootRef', ['FirebaseUrl', Firebase])
.factory('itemFactory', ItemFactory)
.controller('MyCtrl', MyCtrl);
function ApplicationConfig($routerProvider) {
$routeProvider.when('/', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
item: function(itemFactory, $routeParams) {
// return a promise
// the resolved data is injected into the controller
return itemFactory($routeParams.id).$loaded();
}
}
});
}
function ItemFactory(rootRef, $firebaseObject) {
function ItemFactory(id) {
var itemRef = rootRef.child('list').child(id);
return $firebaseObject(itemRef);
}
}
function MyCtrl($scope, item) {
$scope.item = item;
// now you can modify $scope.item and then call $scope.$save()
// no need to worry whether it's an update or save, no worrying
// about callbacks or other async data flow
}
Maybe like this
//EDIT answer edited according to your comment
app.controller( "myController", [ "$scope", "$routeParams", function( $scope, $routeParams ) {
$scope.id = $routeParams.id;
$scope.save = function() {
// https://www.firebase.com/docs/web/api/firebase/update.html
// message when the data has finished synchronizing.
var onComplete = function(error) {
if (error) {
console.log('Synchronization failed');
} else {
console.log('Synchronization succeeded');
}
};
var fb = new Firebase( "URL" );
if( $scope.id ) {
// Update
fb.update( { DATA }, onComplete );
}else{
fb.push( { DATA }, onComplete );
}
}
} ] );

run function of a scope in other scope angularjs

How can I run the working code in createAdmobBanner function in another controller?
angular.module('starter', ['ionic', 'starter.controllers'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
var admobid = {};
if (/(android)/i.test(navigator.userAgent)) {
admobid = {
banner: 'ca-app-pub-3815248714018431/123456789'
};
}
function createAdmobBanner() {
AdMob.createBanner({
adId: admobid.banner
adSize: 'SMART_BANNER',
position: 8
});
}
createAdmobBanner();
});
})
I got createAdmobBanner is not defined if I simply do createAdmobBanner() in my controllers. I tried $rootScope but the plugin doesn't seem work with that.
You need to add it into a service or attached in on $rootScope,
$rootScope solution - faster to implement but "dirty"
.run(function($ionicPlatform,$rootScope) { //add $rootScope dependency injection
$rootScope.createAdmobBanner = function(){
AdMob.createBanner( { adId:admobid.banner
adSize: 'SMART_BANNER',
position:8
});
}
$rootScope.createAdmobBanner()
into your controllers, add the dependency $rootScope and call your function $rootScope.createAdmobBanner
Service Solution - cleaner & reusable
Create a new service that has your function
Inject your service into run
call your service function into run
inject your service into controllers
call your service function into controllers
I just found this link here. Give it a try. The important code looks like this:
var admobApp = angular.module('myapp', ['ionic'])
.run(function($ionicPlatform, $ionicPopup) {
$ionicPlatform.ready(function() {
if(window.plugins && window.plugins.AdMob) {
var admob_key = device.platform == "Android" ? "ANDROID_PUBLISHER_KEY" : "IOS_PUBLISHER_KEY";
var admob = window.plugins.AdMob;
admob.createBannerView(
{
'publisherId': admob_key,
'adSize': admob.AD_SIZE.BANNER,
'bannerAtTop': false
},
function() {
admob.requestAd(
{ 'isTesting': false },
function() {
admob.showAd(true);
},
function() { console.log('failed to request ad'); }
);
},
function() { console.log('failed to create banner view'); }
);
}
});
});
The admob stuff is within $ionicPlatform.ready(function() { and is defined like this var admob = window.plugins.AdMob;
Does that help?
Try to define external angular service/factory and provide this service to any controller you need using dependency injection.
This is a good practice to share common logic or data in this way.
EDIT:
angular.module('starter', ['ionic', 'starter.controllers']);
angular.module('starter').factory('bannerFactory',function(){
return {
createAdmobBanner: function(){
window.plugins.AdMob.createBanner({ adId:admobid.banner
adSize: 'SMART_BANNER',
position:8
});
}
}
});
angular.module('starter').controller('anyController',['bannerFactory', function(bannerFactory){
bannerFactory.createAdmobBanner();
}]);
angular.module('starter').run(function ($ionicPlatform,bannerFactory) {
$ionicPlatform.ready(function () {
bannerFactory.createAdmobBanner();
});
});

How to Redirect with MVC when calling $post in angular

So upfront, I am new to angular so I am a little lost with how I want to accomplish a redirect after I post data back to a server:
I have the following in a update:
$http.post("#Url.Action("SaveBranding", "AirlineConfig")", brandModel.model);
Then on the server I have this in my controller:
[HttpPost]
public ActionResult SaveBranding(BrandingViewModel viewModel)
{
if (IsModelStateValid())
{
var airline = GetAirlineFromAirlinePlatformId(viewModel.AirlinePlatformId);
switch (viewModel.PostAction)
{
case "Save":
BrandingViewModel.SaveEntity(viewModel, _db);
var airlineBranding = BrandingViewModel.FromEntity(_db.AirlinePlatforms.Single(x => x.AirlinePlatformId == viewModel.AirlinePlatformId).BrandingViews, viewModel.AirlinePlatformId);
return View("Branding", airlineBranding);
case "Save & Close":
BrandingViewModel.SaveEntity(viewModel, _db);
return RedirectToAction("Edit", "AirlineConfig", new { id = airline.AirlineId });
case "Cancel":
return RedirectToAction("Edit", "AirlineConfig", new { id = airline.AirlineId });
default:
return HttpNotFound();
}
}
return View("Branding"); //Replace this later
}
My routing isnt working and I am lost how to do this so I can navigate to the correct location.
Use window.location to manually redirect in the browser rather than use a server redirect.
The angular way to redirect is using $location service.
angular.module('someModule', [])
.controller('SomeController', ['$scope', '$http', '$location', someController])
function someController($http, $location) {
$scope.brandModel = {};
$scope.submit = function () {
$http.post("#Url.Action("SaveBranding", "AirlineConfig")", brandModel.model).then(function (data) {
$location.path('/url/to/path');
});
}
}
I put this answer here for completeness. I think also $location is more geared up for handling either hash urls or html5mode urls. If you use raw JavaScript, then you either use window.location.hash = "someUrl" or window.location.href = "someUrl". That could be a little caveat for not doing it the "angular" way.
I noticed also that you include that #Url.Action("", ""), when I did my Angular app with MVC in the index page I did this:
angular.module('someModule', [])
.factory('urlService', urlService)
function urlService() {
var service = {
getSaveBrandingUrl: getSaveBrandingUrl
};
return service;
function getSaveBrandingUrl() {
return '#Url.Action("", "")';
}
}
That way I can have all my other scripts separate, and they only rely on a function name so if you change the URL you don't have to go around the app changing all the links. When you inject this into the controller you would do something like:
angular.module('someModule', [])
.controller('SomeController', ['$scope', '$http', '$location', 'urlService', someController])
function someController($scope, $http, $location, urlService) {
$scope.brandModel = {};
$scope.submit = function () {
$http.post(urlService.getSaveBrandingUrl(), brandModel.model).then(function (data) {
$location.path('/url/to/path');
});
}
}
Obviously then you can tie all that up into it's own service to reduce the injection into the controller:
angular.module('someModule', [])
.factory('someControllerService', ['$http', 'urlService', someControllerService])
.controller('SomeController', ['$scope', '$location', 'someControllerService', someController])
function someController($scope, $location, someControllerService) {
$scope.brandModel = {};
$scope.submit = function () {
someControllerService.saveBranding($scope.brandModel.model).then(function (data) {
$location.path('some/url');
});
}
}
function someControllerService($http, urlService) {
var service = {
saveBranding: saveBranding
};
return service;
function saveBranding(branding) {
return $http.post(urlService.getSaveBrandingUrl(), brandModel.model).then(function (data) {
return data.data;
});
}
}

AngularJS eager loading json file

I am new to angularJS. Sorry, If I am not clear with the question.
Here's the issue.
I have a JSON file ranging 20KB in size. When I try to load this file using 'factory' method, I am getting null value.
var app = angular.module('moonApp', []);
app.factory('MainSource', ['$http', function($http){
var data={source:null};
$http.get('/datafile.json',function(output){
data.source=output;
console.log(data.source); // it works
});
return data;
}]);
app.controller('appCtrl',['$scope','MainSource',function($scope,MainSource){
console.log(MainSource.source); // Not works - getting Null value
}]);
For the above code I am getting NULL value in the console. But If i try it inside the $http success method, it renders the json file contents.
Please help me. Thanks in advance.
I am using $resource to read json file. The following code can load a json file for you.
var app = angular.module('moonApp', ['ngResource']);
app.module('moonApp')
.service('MainSource', function($resource) {
return $resource('/datafile.json', {}, {
query: {
method: 'GET',
isArray: true
}
});
})
Now, inject and use the service in controller
app.controller('appCtrl',['$scope','MainSource',function($scope,MainSource){
MainSource.query(function (data) {
$scope.source = data;
console.log($scope.source); // hopefully you'll see the JSON data here
});
}]);
You can define a function on your MainSource factory and return a promise which you are able to resolve in your controller with the then() call. Please give this a try.
app.factory('MainSource', ['$http', function ($http) {
function getSource() {
return $http.get('/datafile.json', function () {
});
}
return {
'getSource': getSource
}
}]);
app.controller('appCtrl', ['$scope', 'MainSource', function ($scope, MainSource) {
MainSource.getSource().then(function (response) {
console.log(response);
});
}]);
Try like this:
console.log(MainSource.data.source);

Categories