I would like to update the view even if the change happened from a different computer without refreshing the page.I tried to set interval and call my api every ten seconds,clear my cache.The problem here is that every ten seconds i would have to reload all my data and for the view to be update i should switch states.Is there a better way to handle this?
im managed to resolve the issue.I created a function that check if the data from server is equal with the data from the model and if not i update the cache without deleting it and the model.
this.refresh = function(){
apiService.someFunction(false) //the false is parametr for cache
.then(function(someValue) {
if(someValue.length !== vm.model.length){ //check if the model is equal with the data from database
var cache = $cacheFactory.get('$http')
var get = cache.get('URL'); //getting the cache
var data = angular.toJson(someValue); //turn response from then to Json
get[1] = data; //changing the cache data
vm.model= someValue; //changing the model data
}
})
}
Related
I have a typical ngrx-data arrangement of 'User' entities linked to db.
I implement the standard service to handle the data:
#Injectable({providedIn: 'root'})
export class UserService extends EntityCollectionServiceBase<UserEntity> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('User', serviceElementsFactory);
}
}
I read the data using:
this.data$ = this.userService.getAll();
this.data$.subscribe(d => { this.data = d; ... }
Data arrives fine. Now, I have a GUI / HTML form where user can make changes and update them. It also works fine. Any changes user makes in the form are updated via:
this.data[fieldName] = newValue;
This updates the data and ngrx-data automatically updates the entity cache.
I want to implement an option, where user can decide to cancel all changes before they are written to the db, and get the initial data before he made any adjustments. However, I am somehow unable to overwrite the cached changes.
I tried:
this.userService.clearCache();
this.userService.load();
also tried to re-call:
this.data$ = this.userService.getAll();
but I am constantly getting the data from the cache that has been changed by the user, not the data from the db. In the db I see the data not modified. No steps were taken to write the data to db.
I am not able to find the approach to discard my entity cache and reload the original db data to replace the cached values.
Any input is appreciated.
You will need to subscribe to the reassigned observable when you change this.data$, but it will be a bit messy.
First you bind this.data$ via this.data$ = this.userService.entities$, then no matter you use load() or getAll(), as long as the entities$ changed, it fire to this.data$.subscribe(). You can even skip the load and getAll if you already did that in other process.
You can then use the clearCache() then load() to reset the cache.
But I strongly recommand you to keep the entity data pure. If the user exit in the middle without save or reset, the data is changed everywhere you use this entity.
My recommand alternatives:
(1) Use angular FormGroup to set the form data with entity data value, then use this setting function to reset the form.
(2) Make a function to copy the data, then use this copy function as reset.
For example using _.cloneDeep.
(2.1) Using rxjs BehaviourSubject:
resetTrigger$ = new BehaviourSubject<boolean>(false);
ngOnInit(){
this.data$ = combineLastest([
this.resetTrigger$,
this.userService.entities$
]).subscribe([trigger, data])=>{
this.data = _.cloneDeep(data)
});
// can skip if already loaded before
this.userService.load();
}
When you want to reset the data, set a new value to the trigger
resetForm(){
this.resetTrigger$.next(!this.resetTrigger$.value)
}
(2.2) Using native function (need to store the original):
this.data$ = this.userService.entities$.pipe(
tap(d=>{
this.originData = d;
resetForm();
})
).subscribe()
resetForm:
resetForm:()=>{
this.data = _.cloneDeep(this.originData);
}
I have a api data, fetching it and showing it in website using AngularJS. I am just trying to store the api data in local storage rather than fetching data from api everytime. So I coded like this:
if($window.localStorage.cityApi){
$scope.cities = JSON.parse($window.localStorage.cityApi);
}
AddCityService.init(function(city_response) {
$scope.loading = false;
$scope.cities = city_response.data;
$scope.city = JSON.parse(JSON.stringify(getCity($stateParams._id)));
$window.localStorage.cityApi = JSON.stringify($scope.cities);
});
But the problem is, it is taking the data from api, not from the local storage. If I comment the code of getting response from api. it will fetch from the local storage. If I also mention api along with the local, it will take the data from the api. I've checked in chrome developer tools. I can't use else condition too for this.because i have the pages to add the city and show the added cities. if i add the city once, that will redirect to the page to show the added cities. So, now if i use else here, that will not move to else statement itself, Hence it will not show the added city. Can anyone tell me is there any way to do this.
How is it possible that you can't use an else statement here?
if($window.localStorage.cityApi){
$scope.cities = JSON.parse($window.localStorage.cityApi);
}
else {
AddCityService.init(function(city_response) {
$scope.loading = false;
$scope.cities = city_response.data;
$scope.city = JSON.parse(JSON.stringify(getCity($stateParams._id)));
$window.localStorage.cityApi = JSON.stringify($scope.cities);
});
Does this not work?
I want to retrieve data from firbase with a condition like this
ref.orderByChild('users').equalTo(userid).on('value', function(snapshot) {
// Need to return data as firebaseArray here
});
$firebaseArray is very useful when we want to show data on view. But I don't know how to return the snapshot there.
Please help me ! (bow)
A $firebaseArray can take in a ref or a query.
var query = ref.orderByChild('users').equalTo(userid);
var syncArray = $firebaseArray(query);
The array function handles all the child events and keeps the array in sync with the remote server changes.
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
So basically, I created a Backfire app. As soon as the page is loaded, I am iterating over my Backbone.Firebase.Collection instance.
And then rendering the results onto the page... the problem is that obviously the collection instance does not contain all the data that is on firebase.
So, I put a set-timeout of 1000ms to make it so that the collection has time get its data from Firebase. This way of doing it is terrible... sometimes the data is synced up other times it is not.
How can I have an event be triggered as soon as the "BackFire Collection Model" has its data from firebase?
$(document).ready(function() {
var myCatalogApp = new CatalogApp()
var catalog = new Catalog()
setTimeout(function(){myCatalogApp.displayCollection(catalog)},1000);
//To give catalog time to asynchronously retrieve database entries
myCatalogApp.initialize()
})
var Catalog = Backbone.Firebase.Collection.extend({
model: Item,
firebase: "https://mycatalogmaker.firebaseIO.com/items"
});
All of my problems would be solved if Backfire would let me do a fetch method... but they have it disabled for Backfire objects
Try this :
$(document).ready(function() {
var myCatalogApp = new CatalogApp()
var catalog = new Catalog();
catalog.bind('sync', function(){myCatalogApp.displayCollection(catalog);});
myCatalogApp.initialize();
})