Ng-Repeat not updating until page is refreshed - angularjs

To give a brief rundown of what I am working on:
This app is a phonebook that makes a call to our backend system and returns a JSON payload which is then parsed and stored to Local Storage for offline access and then the data is reflected in a simple homescreen format.
To give a simple workflow:
User logs in
Call to back-end via Ajax request is made under the user's account
Data is stored to local storage
Data is added to $rootScope.allEmployeeInformation variable
Ion-List reflects the data stored in the $rootScope.allEmployeeInformation variable on the home screen.
My issue lies here:
After logging in the data is pulled and stored properly but the Ion-List does not display the data until the page is refreshed either via the pull to refresh functionality I have implemented, the re-sync button or restarting the app.
Is there any way to ensure that these pieces of data are displayed without the user needing to refresh the page?
Would be more than happy to provide anymore information needed. Thank you for the help guys!
Edit, updating with some code as requested:
Code which performs the ajax request
Html which displays the information:
<ion-view>
<ion-content class="scroll-content has-header animated fadeIn" ng-controller="HomeScreenController" padding="true">
<ion-refresher
pulling-text="Pull to resync...."
on-refresh="resyncEmployees(true)">
</ion-refresher>
<ion-list>
<ion-item
class="ion-item-content"
ng-repeat="employee in allEmployeeInformation | orderBy:'lastName'"
ng-controller="AccountCtrl"
ng-click="changeTabb(1, {{employee.identifier}})">
<div class="item-icon-left">
<i class="icon ion-person"></i>
<h3>{{employee.userCN}}</h3>
<h5>{{employee.title}}</h5>
<h6>{{employee.town}}</h6>
</div>
<div class="item-icon-right">
<i class="icon ion-chevron-right icon-accessory"></i>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
Edit #2: I believe I've narrowed to down to infact being an issue with ng-repeat and not Ion-List as I expected at first glance. Updating the reference tags.
Cheers!
Mike

Pretty easy - you're using jQuery's $.ajax and that doesn't trigger a digest cycle. Digest cycles are what tell Angular to update and 2 way bind essentially (dumbed down). Use the provided Angular $http module.
$http.get(agent).then(function(response) {
});
Also, you're calling location.reload() at the end of your code - which will get rid of any client changes you've made so far. You probably don't need that.

Without seeing any code, you could also try setting cache: false in the routes config. See example below:
.state('dashboard', {
cache: false,
url: '/dashboard',
views: {
'menuContent' : {
templateUrl: 'templates/dashboard.html',
controller: 'DashboardController',
}
}
})
If you have any code available to post I may be able to help more.
EDIT
Why do you need to use $rootscope? You should also try using $scope instead because you will always have access to the employee information in localStorage if you want to use it in another view or controller.

Related

AngularJS ui-router - Generated <href="">returns current url

I'm new to angularjs and have been scouring for an answer to this problem but to no luck I can't find one.I know that angular (1.x) is older but I still wanted to learn this anyway.
Moving on, I'm trying to dynamically generate links based on a $scope.menu_item object inside a controller of my module. For example if
$scope.menu_items = ['Home','Profile','Settings']
the values in the array correspond to child states of parent state User and is configured using $stateProvider.state()
$stateProvider
.state('user'{
url:'/user',
abstract:true,
templateUrl:'someTemplateThatSeemsToWork',
controller:'MenuCtrl'})
//these are the child states
.state('user.Home',{
url:'/home',
template:'<p>Home</p>' (this is loaded in the template of its parent)
})
.state('user.Profile',{
url:'/profile',
template:'<p>Profile</p>'
})
.state('user.Settings',{
url:'/settings',
template:'<p>Settings</p>'
})
then this in the template using ng-repeat:
<li ng-repeat="menu_item in menu_items">
<a ui-state="user.{{menu_item}}">{{menu_item}}</a>
</li>
As expected, it renders the view properly, the values from $scope.menu_items are properly made into links but the href="" attribute of the tag is equal to the current url.
The default state is 'user.Home' and as such /user redirects to /user/home
(localhost:[port]/user/home)
<a ui-state="user.Home" class="ng-binding" href="/user/home">Home</a>
...
<a ui-state="user.Profile" class="ng-binding" href="/user/home">Profile</a>
...
<a ui-state="user.Settings" class="ng-binding" href="/user/home">Settings</a>
Here we see that all of the generated tags have the href value set to the current url (localhost:[port]/user/profile will make it into href="/user/profile")
So is there anything that I'm forgetting to do? From my understanding, it should work when I use ui-state since it can handle $scope properties.
Some additional notes:
1.) Manually typing the specified state url in the address bar works just fine and renders the correct template
2.) I am using Express to handle the server-side
3.) I set $locationProvider.html5Mode(true)
Temporary Work-around
For the people who might stumble upon this question, I temporarily used a work-around solution and just removed ui-sref="" or ui-state="" and just used
ng-href={{state.url}}
with
ng-repeat= "state in states"
where
states = [{name="stateName", url="/relativeToRootUrl"},{..more States}]
I'd still appreciate a solution for this using ui-sref since it utilized ui-router more.

Ionic InAppBrowser - how to print a variable value in single quotes

I am trying to print the value of merchant.merchant_url for my inAppBroswer call. I have looked at the recommended javascript to parse using the A tag at the blog by Nic. https://www.thepolyglotdeveloper.com/2014/12/open-dynamic-links-using-cordova-inappbrowser/
However, this impacts my other links on the app that I do not need to open in the InAppBrowser. Can someone please recomend how can I print this url value? I tried ng-href as well but then the opened site takes over the app and there is no way to exit.
I have also tried using ng-click as suggested here How do I open inAppBrowser using Angular JS?
But this doesn't help either. I know for a fact that merchant.merchant_url has value because i can print it outside my a href. However I having trouble getting it in single quotes for the execution. I have tested non-dynamic links and they work fine in the app. Stripped off < > for the so that the code is readable.
a class="item" href="#" onclick="window.open('{{merchant.merchant_url}}', '_blank', 'location=yes'); return false;"
View
/a
Past this code your controller:
$scope.urlOpen = function(url) {
console.log(url);
window.open(url, '_blank', 'location=yes');
};
and change in your view:
<a class="item" href="#" ng-click="urlOpen({{merchant.merchant_url}})">View </a>
Most of the code posted by xuser is ok. Except that merchant.merchant_url has to be in single quotes.
urlOpen('{{merchant.merchant_url}}')

RESTful routing to single firebase object from firebase array

I am confused on how to do a very, very trivial pattern with angular/firebase using angularfire.
Imagine you have a lil' old blog. You have some $scope.posts and you ng-repeat over them. Now you want to be able to click on one post and be routed to that post's page at '/posts/:id'. Since a $firebaseArray elements don't include their $id's how do you pass a unique id of a single post to the url and onto the postsCtrl?
<a ng-repeat="post in posts href="/posts/{{??????}}">{{post.title}}</a>
Update
The workaround I figured out is whenever I save a new post, I can save an attribute called "key" and then use this the way I would normally use the "id" attribute in every other framework.
$firebaseArray(postsRef).$add($scope.post).then(function(ref) {
ref.update({ key: ref.key()});
});
This hack, however, cannot be the solution to this simple, trivial, conventional pattern.
Thanks for any help.
You're instincts are right, that hack isn't the answer. Instead use angular's built in (key, value) option for ng-repeat:
<div ng-repeat="(id, post) in posts">
<a ng-href="/posts/{{post.id}}">{{post.title}}</a>
</div>
Additional reference material on how to use AngularFire with ng1 can be observed in this repo

ionic: ion-item in ion-list triggers page reload (ui.router)

i am using ionic (the original one, not meterionic) within meteorjs.
when i am using ion-item with a href the page is reloading, what i dont want to.
i tried to use and is normally changing the state without reloading.
How can i change the behavior of ion-item to change only the state without reloading the whole single-page-application?
<ion-list>
<ion-item href="/home">Home (Page Reload)</ion-item>
<ion-item>Home (no Page Reload)</ion-item>
</ion-list>
ok, that one was obvious. it has to look like that:
<ion-item ui-sref="app.home">Home</ion-item>
try to put a hash before the slash href="#/home" or just use ui-sref ui-sref="home"

Angular click for new page with infomation from clicked item JSON

I have a product page, and there is an option for a 'quick view' which opens the product description and images in a modal. I also have a 'full details' button where I would like the user to be taken to a new URL based on the item code, but also display the information from my JSON for that clicked product. This is what I have:
<a ng-click="store.selected = product" ng-href="{{store.selected.code}}.html" class="btn btn-sm">Full details</a>
Everything works great for the Modal, so I am presuming there is a problem moving onto a different page and carrying this information across? I have mocked it up in Plunker to show the problem:
Plunker here
Any help would be much appreciated.
You should consider using ng-route to switch the view to a different html file. But you can also use ng-include with a little less set up.
When the Full details link is clicked, toggle a variable that tracks whether the gallery or the details should be visible. And, construct the path to the html template you want to display:
$scope.setSelection = function(product) {
$scope.store.selected = product;
$scope.detail.show = !$scope.detail.show;
$scope.detail.source = product.code + '.html'
}
Then, use ng-include to display the template:
<div ng-if="detail.show" ng-include="detail.source">
</div>
Here is an update of your plunker: http://plnkr.co/edit/zhsY6TAjONewyInGiwUC?p=preview
Note that the template should just be a snippet of html.. you don't need to include scripts like angular again.

Resources