How to reload the ionic view? - angularjs

I have created a sidemenu based app, in that after login I am displaying a number of tasks. If I click on the task it will redirect to the task details page, in that page I can update the tasks.
So after updating a task I need to go back to the previous task list page. I am using $ionicHistory.goBack(); to go back.
My problem is after come back, I need to refresh the task list i.e. updated task should not be there in the task list. How can I refresh/reload the task list?

If you bind your task to a tasks array, which will be used in the task list page, it should be automatically updated.
But the question is about not displaying, newly added tasks (still my previous suggestion should work) if not, performance reasons ionic views are cached, So when you come back to the previous view it doesn't go through the normal loading cycle. But you 2 options
1 - disable the caching by using <ion-view cache-view="false" view-title="My Title!"> in your ion-view, but this is not a very elegant solution. read more
2 - use ionRefresher (my preferred). read more here

https://github.com/angular-ui/ui-router/issues/582
according to #hpawe01 "If you are using the current ionicframework (ionic: v1.0.0-beta.14, angularjs: v1.3.6, angular-ui-router: v0.2.13), the problem with the not-reloading-controller could be caused by the new caching-system of ionic:
Note that because we are caching these views, we aren’t destroying scopes. Instead, scopes are being disconnected from the watch cycle. Because scopes are not being destroyed and recreated,controllers are not loading again on a subsequent viewing.
There are several ways to disable caching. To disable it only for a single state, just add cache: false to the state definition.
This fixed the problem for me (after hours of reading, trying, frustration).
For all others not using ionicframework and still facing this problem: good luck!"
Hope this helps.

You can also listen to ionic events such as $ionicView.enter on $scope and trigger the code that refreshes the list if you haven't bound your list as #sameera207 suggested.
EG:
// List.controller.js
angular.module('app')
.controller('ListController', ['$scope', function($scope) {
// See http://ionicframework.com/docs/api/directive/ionView/ for full events list
$scope.$on('$ionicView.enter', function() {
_someCodeThatFetchesTasks()
.then(function(tasks) {
$scope.tasks = tasks;
});
});
});
Bear in mind that it's not the most proper way (if proper at all) and if you do this you certainly have a design flaw. Instead you should share the same data array via a factory or a service for example.

For your task you can also use ion-nav-view.
It is well documented. And if you are using now Ionic 2 beta you can use some of the view lifecyle hooks like onPageWillLeave() or onPageWillEnter(). I just faced the same problem and defined a refresh() function, but the user had to click on a button to actually update the view. But then I found:
https://webcake.co/page-lifecycle-hooks-in-ionic-2/
You just have to import the Page and NavController module and also define it in the constructor. The you can use for example onPageWillEnter(), which will always invoke when you go again to a view:
onPageWillEnter() {
// Do whatever you want here the following code is just to show you an example. I needed it to refresh the sqlite database
this.storage.query("SELECT * FROM archivedInserates").then((data) = > {
this.archivedInserates =[];
if (data.res.rows.length > 0) {
for (var i = 0; i < data.res.rows.length; i++) {
this.archivedInserates.push({userName:data.res.rows.item(i).userName, email:
data.res.rows.item(i).email});
}
}
},(error) =>{
console.log("ERROR -> " + JSON.stringify(error.err));
});
}
With ionic beta 8 the lifecylcle events changed their names. Check out the official ionic blog for the full list of the lifecycle events.

if you are building data driven app then make sure use $ionicConfigProvider.views.maxCache(0);in your app.config so that each review can refresh for more details read this http://ionicframework.com/docs/api/provider/$ionicConfigProvider/

Related

using angularjs to refresh view's data automatically when the data in database is changed

is it possible to use angularJs to refresh view's data automatically when the data in database is changed? Please help me how to do it
I made this script, but as you can see the data only refresh if viewData() is triggered.
$scope.viewData = function(){
$http.get("sample.php").then(function(response){
$scope.mine = response.data;
});
}
I want to create page like timeline in twitter which can load new tweets without refreshing the page. Thank you
You can do longpolling like this from Angular side:
setInterval($scope.vievData, 1000);
since setInterval is not monitored by Angular you will have to add the following line in $scope.viewData
$scope.$$phase || $scope.$digest();
immediately after $scope.mine=...
This will refresh $scope.mine every second regardless of the changes in DB, it is a bit crude. To do this only when the values are changed in the database you will probably have to use WebSockets, but that is a bit more complex, both front and back.

Prevent Firebase $firebaseArray auto update

I am working on a News Feed that is similar to Facebook News Feed. I am implementing it in the following sequence:
When app is started, get everything, but only push two item to show.
The user can scroll down to see more and I will add more to the list.
If there are any new items, the user needs to pull to refresh to add the new ones.
The only problem I have right now is that each time an item is added, $firebaseArray automatically adds the new item to my array that I do not want snyc changes (I want to query once, get a set list). I was wondering if anyone would know how to prevent the auto update?
Look into .once this will allow you to get the data just once: https://firebase.google.com/docs/reference/js/firebase.database.Query#once
Instead of binding directly your $firebaseArray to the view, clone it to a scope (or controller) property that will be bound to the view. Factorize this process in a function you can call when the user pull-reloads so the the $firebaseArray is re-created.
A more appropriate approach would be to use Firebase's http api, with the angular $http service.
Edit: to clone the array to a scope var, try the following:
var allEvents = $firebaseArray(queryOfeverything);
allEvents.$loaded()
.then(function(events){
$scope.allEvents = angular.map(events, function(event) {
return event; // you may want to replace this line - I am not very familiar with firebase.
})
});

Why calling different subscription on the same collection cause error in meteor?

I working on this angular-meteor tutorial step 12
an I have a question in
Stopping a subscription Topic
you can use ctrl+f using "meteorSubscribe"
then the key sentence on that topic is
The reason is that we are calling a different subscription on the same collection inside the partyDetails controller.
the code before correction is
$scope.party = $meteor.object(Parties, $stateParams.partyId).subscribe('parties');
$scope.users = $meteor.collection(Meteor.users, false).subscribe('users');
then after correction
$scope.party = $meteor.object(Parties, $stateParams.partyId);
$scope.users = $meteor.collection(Meteor.users, false).subscribe('users');
$scope.$meteorSubscribe('parties');
I try to run before correction code and nothing(error) show in cmd but it just cause the wrong result as tutorial say
if you navigate to the party details page and then go back, pagination and search will stop working.
Then i got two question
Why no error show on cmd?
Why error from partyDetails controller affect to partiesList controller search and pagination? What is their relation?
EDIT: If you don't cancel a subscription, then if you navigate away and back again you will end up trying to subscribe twice to the same publication, resulting in the error, because subscriptions in meteor last until you end them.
There are two ways to get rid of a subscription with angular-meteor. One you can assign a handle variable to the subscription and then on navigating away from the page you can stop it. Two (the recommended way) is to use $scope.$meteorSubscribe instead of $meteor.subscribe() because it is set up to automatically remove the subscription when the scope is destroyed.
I can't see all of your code to know for sure why you are or are not getting the errors you think you should, hopefully this sheds some light on what is going on in the tutorial.
The very end result would be something like:
$meteor.autorun($scope, function() {
$meteor.subscribe('parties', {
limit: parseInt($scope.perPage),
skip: parseInt(($scope.page - 1) * $scope.perPage),
sort: $scope.sort
}).then(function() {
$scope.partiesCount = $meteor.object(Counts, 'numberOfParties', false);
$scope.parties = $meteor.collcetion(function() {
return Parties.find({}, {
sort: $scope.getReactively('sort');
});
});
});
});
Notice that he's also changing the publish function on the server. It helps to understand if you click the links to show the git diffs.

is it right to do using ui-router to activate menu items. Any advices to help me understand this?

What I did is:
When a menu item is clicked, a action will be done, like deleting a user, sending emails to a group, etc. To this end, for each menu item, I define a ui-router state, and use the state url to activate the state via sref. I thought that a menu action is just a UI component for user to let users to do something, which is just a state of UI.
I was advised that I was using ui-router in a wrong way as a state url can not identify an action. For example, to delete a group of users, the state url can not tell you what group of users have been deleted.
In short, I agree with your manager while being an angular newbie myself. Angular routes are designed for managing different views of your app. I.e. define a route and corresponding view template for each view. If you add application logic into the routes, your application structure gets quickly a mess and difficult to keep clear.
To me it is much more natural that the views are managed by the routes, and each action in each view is handled by the controller of that view. If the actions grow "big", then it is worth refactoring parts of the controller into separate services. If you require some sort of "dynamic HTML" depending on the action, e.g. bootstrap modals are handy for doing that within the current view (see http://angular-ui.github.io/bootstrap/).
E.g. in my current project, I don't actually manually edit the routes at all but let yeoman angular generator to do that for me free of charge - i.e. I instantiate each new view in my dev.env using the following command (more info on this from https://github.com/yeoman/generator-angular)
yo angular:route myNewView
More info on angular philosophy can be read from angular documentation for developers: https://docs.angularjs.org/guide/concepts
You should probably be doing this actions via a method on $scope.
$scope.deleteItem = function (items) {
Service.delete(items);
};
// which is the same as:
$scope.deleteItem = Service.delete;
<a ng-click="deleteItem(item)">Delete This Item</a>
Having it in the URL just seems wrong. I mean what does that look like? www.mysite.com/delete/users?

How come Angular doesn't update with scope here?

I'm pretty new to Angular and I'm using firebase as my backend. I was hoping someone could debug this issue. When I first go to my page www.mywebsite.com/#defaultHash the data doesn't load into the DOM, it does after visiting another hash link and coming back though.
My controller is like this:
/* initialize data */
var fb = new Firebase('https://asdf.firebaseio.com/');
/* set data to automatically update on change */
fb.on('value', function(snapshot) {
var data = snapshot.val();
$scope.propertyConfiguration = data.products;
console.log($scope.propertyConfiguration);
console.log("Data retrieved");
});
/* save data on button submit */
$scope.saveConfigs = function(){
var setFBref = new Firebase('https://asdf.firebaseio.com/products');
setFBref.update($scope.propertyConfiguration);
console.log("configurations saved!");
};
I have 3 hash routes say "Shared", "Registration", and "Home" with otherwise.redirectTo set to "Shared".(They all use this controller) Here's the error that occurs: (all "links" are href="#hashWhereever")
1) Go to website.com/#Shared or just refresh. Console logs $scope.propertyConfiguration and "Data Retrieved". DOM shows nothing.
2) Click to website.com/#Registration, console logs $scope data properly, DOM is loaded correctly.
3) Click back to website.com/#Shared, console logs $scope data properly yet this time DOM loads correctly.
4) Refresh currently correctly loaded website.com/#Shared. DOM elements disappear.
Since $scope.data is correct in all the cases here, shouldn't Angular make sure the DOM reflects the model properly? Why is it that the DOM loads correctly only when I am clicking to the page from another link.
I can "fix" it by adding window.location.hash = "Shared" but it throws a huge amount of errors in the console.
FIXED:(sorta)
The function $scope.$apply() forces the view to sync with the model. I'd answer this question myself and close it but I'm still wondering why the view doesn't load correctly when I correctly assign a value to $scope. If Angular's "dirty checking" checks whenever there is a possibility the model has changed, doesn't assigning a value to $scope overqualify?
Angular has no way to know you've assigned a value to $scope.variable. There's no magic here. When you run a directive (ng-click/ng-submit) or Angular internal functions, they all call $apply() and trigger a digest (a check of the dirty flags and update routine).
A possibly safer approach than $apply would be to use $timeout. Currently, if you call a write op in Firebase, it could synchronously trigger an event listener (child_added, child_changed, value, etc). This could cause you to call $apply while still within a $apply scope. If you do this, an Error is thrown. $timeout bypasses this.
See this SO Question for a bit more on the topic of digest and $timeout.
This doc in the Angular Developer Guide covers how compile works; very great background read for any serious Angular dev.
Also, you can save yourself a good deal of energy by using the official Firebase bindings for Angular, which already take all of these implementation details into account.
Vaguely Related Note: In the not-too-distant future, Angular will be able to take advantage of Object.observe magic to handle these updates.

Resources