ion side menu, make it update once content change - angularjs

I have an app made with ionic-framework.
I have a button that makes a user follow another user. The button posts to the API and it saves.
In the ion side menu, I list all the people I follow, which I get from the same API.
However, when I follow another user, the ion side menu doesn't update as it is cached I suppose. How do I make it update once I follow another user?
Thank you.
Users profile controller
$scope.toggleFollow = function(bool)
{
$http.post('http://localhost:26264/api/follow?userId=' +$stateParams.userId +"&toggleFollow=" +bool);
}
Left menu controller
$http.get('http://localhost:26264/api/follow').then(function(resp) {
console.log('Success', resp);
$scope.alternatives = resp.data;
Then I just loop out the $scope.alternatives in the left menu like
<ion-item ng-repeat="alternative in alternatives" href="#/app/user/{{ alternative.id }}">
{{alternative.name}}
</ion-item>

You need to update $scope.alternatives
For that, as we don't know your logic and code.
You can do the following :
Solution 1: Creating an event emiter & receiver :
From first controller : you can $rootScope.$broadcast("myEvent",{info : myNewAlternativesInfo});
From Second Controller : $scope.$on("myEvent",args){ //update as needed alternatives with access to args.info
Solution 2: access to data from a service
Both controller update and access to values from a shared Service
Then you just need to add on your second controller a watcher on the desired value to check when it updated $scope.$watcher
If that's not enough to lead you to solution, gives us more info ;)

Related

communicating between two controller in angularjs using factory

I have created a plunker that communicates between two different controller in nested views using factory. Below is the url of plunker.
https://plnkr.co/edit/fWA2Xugjbkf3QvHKfTa0?p=preview .
Here is the factory.
routerApp.factory("widgetService",function($state){
var callbackFunctions=[];
var counter=0;
var addWidget=function(name){
callbackFunctions[0](name);
}
var addCallback=function(callback){
if (callbackFunctions.length===0) {
callbackFunctions.push(callback);
}
}
return{
addCallback: addCallback,
addWidget: addWidget
}
})
Scenario 1:
1. Click on "List" menu under the home page.
2. Click on "verify" button. notice the change in highlighted area with yellow. Text changes from "Chandan" to "singh1".
3. Click again on verify button. Text changes from "singh1" to "singh2". So i am able to communicate between two controller in this.
Scenario 2:
1. Repeat the scenario 1 till step 2.
2. Click on "PARAGRAPH" menu under home page.
3. Click on "List" menu under home page. Click verify button. The text wont change. It will remain "chandan".
Communication is not working as we change the state.
Also i have observed that the model is changing but same is not getting reflected in view. Moreover if we bind the view to rootscope, view is getting updated.
Please clarify.
When you switch between list and paragraph states, your list controller is destroyed (and recreated next time you go to list). So when it is recreated it gets a new scope.
The callbackFunction that is registered in your service, refers to the changeMyName() function on the old controller scope, so whenever you call addWidget() in your service, you're actually calling the callback in your old scope.
To make this work as expected (at least in your sample code here), you would have to change your service to allow changing the old callback in the addCallback()-function. Something like this:
var addCallback=function(callback){
callbackFunctions[0] = callback;
}

ionic1 wait http response of next view before load it

i'm using ionic to create an application who retrieve data from api through http request when I change view I see the view before the data of the controller totally loaded :
How can I load data of the next controller to only see the final result :
here the button who start the change of view :
<ion-item class="item-thumbnail-left item-icon-right" ng-repeat="inscription in inscriptions" ng-click="loadActiProfil({{inscription}})" href="#/app/activite">
thank you in advance
You shouldn't wait for your HTTP response to start the navigation transition, on a UX perspective. ionic provides a service called $ionicLoading which allows displaying and hiding a spinner (with a black&transparent backdrop). You may use it to make your user understand that he/she's supposed to wait. But enough with my personal opinion.
Regarding your need:
Do not use href to change the current state, you'd rather use ui-sref, as it's supposed to be done using angular-ui router (which is, of course, ionic's router too). NB: ui-sref expects a state name and not an URI (for instance, "app.home").
Use your method loadActiProfil to programmatically switch from the previous state to the new one only once your data is available, thanks to the service $state and its method go (ie: $state.go('app.home') will take you to the state app.home)
TL;DR: if you need to switch the current state programmatically, then use $state.go(stateName), not ui-sref (nor href).

Pass service result to other controller

I am calling getLanguageSpecificData(LangCode) service from home controller and saving the data into localStorage. On Home page there are Language links, if user click on English then it will redirect to a second template. But the problem is that still home controller getLanguageSpecificData(LangCode) service is not completed its execution.So in second Controller when I am trying to get result from localStorage it is incorrect(not updated).
So can you please tell which is better approach in this situation ?
HomeController code :
app.controller('homeController',function($scope,$localStorage,$appService){
$scope.loadlanguagefile = function(langcode){
$troubleshootingService.getLanguageSpecificData(LangCode).then(function(responce){
$localStorage.data = responce.data;
});
}
});
'loadlanguagefile' function is called when user click on Enlgish link and app is redirect to second template. here is secondController code :
app.controller('secondController',function($scope,$localStorage){
$scope.data = $localStorage.data;
});
As per my suggestion, you should use callback function to do your need full, when the function is called make the English click disable , and if your result is successful the make that enable. It will be something like this:
getLanguageSpecificData(LangCode,callback:(dataToReturn:any)=>void):any{
//logic here to get data to return
callback(dataToReturn);
}
For calling this method -
1- before calling the method make English click disable.
2- then call the method-
getLanguageSpecificData(imputLangCode,(result)=>{
//logic for data modification
//logic to enable English click
});
3- Enable the English click inside the call of the method.

How to reload the ionic view?

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/

Backbone.js: How to utilize router.navigate to manipulate browser history?

I am writing something like a registration process containing several steps, and I want to make it a single-page like system so after some studying Backbone.js is my choice.
Every time the user completes the current step they will click on a NEXT button I create and I use the router.navigate method to update the url, as well as loading the content of the next page and doing some fancy transition with javascript.
Result is, URL is updated which the page is not refreshed, giving a smooth user experience. However, when the user clicks on the back button of the browser, the URL gets updated to that of a previous step, but the content stays the same. My question is through what way I can capture such an event and currently load the content of the previous step and present that to the user? Or even better, can I rely on browser cache to load that previously loaded page?
EDIT: in particular, I'm trying something like mentioned in this article.
You should not use route.navigate but let the router decide which form to display based on the current route.
exemple :
a link in your current form of the registration process :
<a href="#form/2" ...
in the router definition :
routes:{
"form/:formNumber" : "gotoForm"
},
gotoForm:function(formNumber){
// the code to display the correct form for the current url based on formNumber
}
and then use Backbone.history.start() to bootstrap routing

Resources