how can I fetch this data to html page using angular.js? - angularjs

var gamedataRef = firebase.database().ref('gamedata');
gamedataRef.on('child_added', function(data) {
$scope.abc = data.val().textgame;
});
I have to find this.

Firebase data is loaded asynchronously. This is great, because it allows the browser to continue being responsive while the data is being loaded. But unfortunately it also means that AngularJS is not expecting updates anymore by the time the data comes back.
The solution is to tell AngularJS when the data comes back, with for example $timeout():
var gamedataRef = firebase.database().ref('gamedata');
gamedataRef.on('child_added', function(data) {
$timeout(function(){
$scope.abc = data.val().textgame;
});
});
You might also want to have a look at AngularFire, an open-source binding library that solves this problem and a lot of others you're likely to run into.

Related

how to clear the browser cache on the application load without effecting pagination?

I am working on angular js application.
For the first time application is working fine, when we release a new build with new changes, when the user trying to access the page browser is still loading the old files new changes are showing in the browser, to load the new changes user has to clear the cache and reload the application.
Is there any way to clear the browser cache on the application load.
I am clearing the cache like below.
function run($rootScope,$state, $stateParams, authorization, principal,$templateCache) {
//code to clear the cache.....
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
}
it is clearing the cache, but pagination is not working after adding this code into application .
Any help appreciated, thanks in advance.
Try to set version for all of you files and http requests, do not clear the cache!
Want to Browse Faster? Stop Clearing Your Browser Cache
how to set version to files and api requests, you can put a global variable to handle it after each publish for example:
var version = "1.0.0";
var app = angular.module("app", []);
app.config(function(){
//for routes
//pages.html?v="+version
//controller.js?v="+version
})
app.controller("ctrl", function($http){
$http.get("api/posts?v=" + version)
})
with this version you can handle your users browser cache.
This is a common problem, to solve this browser cache issues you need to add some kind of unique identifier (hash/timestamp) to all your static files.
There are lot of backend framework which bundles your file, optimize it and add a unique hash to it which gets changed after any change in the original file.
Tools varies depending upon the back-end framework you are using. This is the ideal approach for handling this issue.
You can check gulp-rev, which is a really good library for re-visioning of your static assets.
To do it quickly, you can use an Interceptor on your main module, and append a version number to every request. You need to make sure that after every release you need to change the version number. The downside of this approach is, even the file which has not be changed will get refreshed.
yourModule.factory('cacheInterceptor',
['$templateCache', '$window', function ($templateCache, $window) {
var cacheInterceptor = {
request: function (request) {
if ($templateCache.get(request.url) === undefined) {
var appVersion = '';
appVersion = $window.MyApp.appVersion;
request.url = request.url + '?appVersion=' + appVersion;
}
return request;
}
};
return cacheInterceptor;
}]);
Note: Version number you need to assign on the window object every time the application loads.
You can find more details on Interceptors in AngularJS here

Passing data to new page using Onsenui

I am trying to call an API end point once a user clicks a button holding a myNavigator.pushPage() request. However,I can not get the $scope data generated from the $http.get request to be passed to the new page.
If I test using console.log('test'); inside the .success of the $http.get request I successfully get the log info in the console but any data held in $scope.var = 'something'; does not gets passed to the page! Really confused!
$scope.historyDetails = function(id){
var options = {
animation: 'slide',
onTransitionEnd: function() {
$http.get('http://xxx-env.us-east-1.elasticbeanstalk.com/apiget/testresult/testId/'+id).success(function(data) {
$scope.testscore = 'something'; // this is not getting passed to page!
console.log('bahh'); // But I see this in console
});
}
};
myNavigator.pushPage("activity.html", options);
}
Page:
<ons-page ng-controller="HistoryController">
...
<span style="font-size:1.2em">{{testscore}} </span><span style="font-size:0.5em;color:#555"></span>
...
</ons-page>
Yes, that's so because both pages has different controllers, resulting in different scopes. One can not access variables from one scope to another.
Hence one solution in this case can be using rootScope service.
Root Scope is parent scope for all scopes in your angular application.
Hence you can access variable of root scopes from any other scope, provided that you are injecting $rootScope service in that controller.
to know more about rootScope check this link.
Good luck.
Update 1:
check these articles
http://www.dotnet-tricks.com/Tutorial/angularjs/UVDE100914-Understanding-AngularJS-$rootScope-and-$scope.html
https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
As Yogesh said the reason you're not getting your values is because if you look at $scope.testscore and try to find where is the $scope defined you will see that it's an argument for the controller function (thus it's only for that controller).
However we can see that the controller is attached to the page and you are pushing another page.
So in that case you have several options:
Use the $rootScope service as Yogesh suggested (in that case accept his answer).
Create your own service/factory/etc doing something similar to $rootScope.
(function(){
var historyData = {};
myApp.factory('historyData', function() {
return historyData;
});
})();
Technically you could probably make it more meaningful, but maybe these things are better described in some angular guides.
If you have multiple components sharing the same data then maybe you could just define your controller on a level higher - for example the ons-navigator - that way it will include all the pages. That would be ok only if your app is really small though - it's not recommended for large apps.
If this data is required only in activity.html you could just get it in that page's controller. For example:
myApp.controller('activityController', function($scope, $http) {
$http.get(...).success(function(data) {
$scope.data = data;
});
}
But I guess you would still need to get some id. Anyway it's probably better if you do the request here, now you just need the id, not the data.
You could actually cheat it with the var directive. If you give the activity page <ons-page var="myActivityPage"> then you will be able to access it through the myActivityPage variable.
And the thing you've been searching for - when you do
myNavigator.pushPage("activity.html", options);
actually the options is saved inside the ons-page of activity.html.
So you can do
myNavigator.pushPage("activity.html", {data: {id: 33}, animation: 'slide'});
And in the other controller your id will be myActivityPage.options.data.id.
If you still insist on passing all the data instead of an id - here's a simple example. In the newer versions of the 2.0 beta (I think since beta 6 or 7) all methods pushPage, popPage etc return a promise - which resolve to the ons-page, making things easier.
$scope.historyDetails = function(id){
myNavigator.pushPage("activity.html", {animation: 'slide'}).then(function(page) {
$http.get('...' + id).success(function(data) {
page.options.data = data;
});
});
});
Side note: You may want to close the question which you posted 5 days ago, as it's a duplicate of this one (I must've missed it at that time).

How to disable firebase 3-way data binding

I am using angularJS 1.3 with angularfire and firebase.
I did create some factories that encapsulate the firebase object, and it works very well. The 3 way data binding is really cool.
I am planning to build a large application using firebase for data persistance, but I am facing a massive issue :
In my business model, I want some models/collections to support 3-way data binding, but I want other collections not to be updated live.
Some clients visiting the resulting website might be scared when they see the website's content being updated live - and I don't want that.
Imagine you are reading an article , somehow long and complexe, and you put your attention into a paragraph which you have issues understanding, and suddenly, the paragraph disappears and is replaced by a new one. Now imagine that you have no idea about web development. You might start to think to consult some professionnal about your mental health, or think your computer is hacked. Who knows !
So I would like to disable the 3 way data binding for this article, and avoid this border-line client phone calls. The only solution I found would be not to use fireangular, and use the beyond angularfire documentation section instead, and remove the following lines :
ref.on("value", function(snapshot) {
$timeout(function() {
$scope.data = snapshot.val();
});
});
This would fix the issue, but then in my admin interface, I would have to implement a second Factory so admin users can access the 3 way data binding for articles - Which is not very DRY.
In my artitcle controller, I would have to write something like this :
$scope.loadArticle = function(){
if(UserService.type === 'admin'){
AdminArticleFactory.get(id);
}
else{
ArticleFactory.get(id);
}
}
Is there any other way of setting up firebase to disable the pull updates?
Yeah, that is what I also ran into. Sometimes you will repeat yourself with Firebase. Also when storing data. I would recommend just making a function to save the data that you don't want to be updated instantly.
<button ng-click="saveChanges">save</button>
In controller
$scope.saveChanges = function () {
var obj = $firebaseObject(ref);
obj.foo = "bar";
obj.$save().then(function(ref) {
ref.key() === obj.$id; // true
}, function(error) {
console.log("Error:", error);
});
}
edit
To desync a firebase object/array you can follow this answer: How to disassociate angularFire bound object?

using data from a callback from Ebay api in Angularjs

I am trying to use the ebay api in an angular.js app.
The way the api works by itself is to pass data to a callback function and within that function create a template for display.
The problem that I am having is in adding the data returned from the callback to the $scope. I was not able to post a working example as I didnt want to expose my api key, I am hoping that the code posted in the fiddle will be enough to identify the issue.
eBayApp.controller('FindItemCtrl', function ($scope) {
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
}
console.log($scope.items); //this is undefined
})
http://jsfiddle.net/L7fnozuo/
The reason the second instance of $scope.items is undefined, is because it is run before the callback function happens.
The chances are that $scope.items isn't updating in the view either, because Angular doesn't know that it needs to trigger a scope digest.
When you use the Angular provided async APIs ($http, $timeout etc) they have all been written in such a way that they will let Angular know when it needs to update it's views.
In this case, you have a couple of options:
Use the inbuilt $http.jsonp method.
Trigger the digest manually.
Option number 1 is the more sensible approach, but is not always possible if the request is made from someone else's library.
Here's an update to the fiddle which uses $http.jsonp. It should work (but at the moment it's resulting in an error message about your API key).
The key change here is that the request is being made from within Angular using an Angular API rather than from a script tag which Angular knows nothing about.
$http.jsonp(URL)
.success($scope.success)
.error($scope.error);
Option 2 requires you to add the following line to your JSONP callback function:
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
$scope.$apply(); // <--
}
This method tells Angular that it needs to update it's views because data might have changed. There's a decent Sitepoint article on understanding this mechanism, if you are interested.

AngularJS calls $http constantly

Im very new to AngularJS (4 hours new) and I'm trying to get an http call working, however what it seems like its happening is Angular keeps calling the http get request over and over again. I'm sure this is because my approach is wrong. This is what I'm trying to do.
snippet of my controller file The webservice works fine. I am running this in a node.js app
function peopleController($scope,$http){
$scope.getPeople = function(){
$scope.revar = {};
$http.get('/location/-79.18925/43.77596').
success(function(data){
console.log(data);
$scope.revar = data;
});
}
}
My list.html file
<div ng-controller="busController">
<div class="blueitem">{{getPeople()}}</div>
</div>
I know I will not see the results since im not returing anything in my getPeople Method but I wanted to see the log output of the result which I did see in chrome, but a million times and counting since angular keeps calling that url method over and over again. Instead it keeps hitting.
How do I get angular to return the response just once?
The problem you are experiencing is linked to the way AngularJS works and - to be more precise - how it decides that a template needs refreshing. Basically AngularJS will refresh a template based on a dirty-checking of a model. Don't want to go into too much details here as there is an excellent post explaining it (How does data binding work in AngularJS?) but in short it will keep changing for model changes till it stabilizes (no more changes in the model can be observed). In your case the model never stabilizes since you are getting new objects with each call to the getPeople() method.
The proper way of approaching this would be (on of the possible solutions):
function peopleController($scope,$http){
$http.get('/location/-79.18925/43.77596').
success(function(data){
$scope.people = data;
});
}
and then, in your template:
<div ng-controller="busController">
<div class="blueitem">{{people}}</div>
</div>
The mentioned template will get automatically refreshed upon data arrival.
Once again, this is just one possible solution so I would suggest following AngularJS tutorial to get better feeling of what is possible: http://docs.angularjs.org/tutorial/
Couple of things. Welcome to angularjs, its a great framework. You probably shouldn't be calling getPeople from the webpage. Instead,
function peopleController($scope,$http){
var getPeople = function(){
$scope.revar = {};
$http.get('/location/-79.18925/43.77596').
success(function(data){
console.log(data);
$scope.revar = data;
});
}
getPeople();
}
and then in html
<div ng-controller="busController">
<div class="blueitem">{{revar|json}}</div>
</div>
Also, I would recommend you looking into the ngResource, especially if you are doing CRUD type applications.
Hope this helps
--dan

Resources