AngularFire – Nested Firebase requests don't work - javascript

I've got the following code in a controller:
FirebaseService.$child('tasks').$on('loaded', function(tasks) {
console.log('tasks loaded');
FirebaseService.$child('taskTemplates').$on('loaded', function(taskTemplates) {
console.log('taskTemplates loaded');
});
});
The console only shows tasks loaded and the second console.log is never executed. If I request those children sequential (the request for taskTemplates is not in the loaded-callback) it works seamlessly. Is there a reason for this strange behaviour?
Some background information: When the tasks are loaded, I need to do check something with them and in some case – and only then – I want to load the taskTemplates.
Here's my FirebaseService, if that's helpful:
app
.value('FIREBASE_URL', 'XXXXXXXXXXXX.firebaseIO.com/')
.service('FirebaseService', function($firebase, FIREBASE_URL) {
return $firebase(new Firebase(FIREBASE_URL));
});
Thank you very much for your help!

My first suspicion was that this error looks similar to this series of bugs, one of which is that loaded only triggered once if declared after initial load. Since FirebaseService calls $firebase on the parent path, all the child data is already cached locally, which would cause the loaded event to be fired synchronously (maybe before you've attached your listener and thus triggering the bug listed above).
However, I was unable to reproduce the behavior you've shown above in angularFire versions 0.6.0, 0.7.0, or the latest master branch. Here's my repro:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<script src="http://cdn.firebase.com/js/client/1.0.6/firebase.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.7.0/angularfire.min.js"></script>
</head>
<body ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="log in logs">{{log}}</li>
</ul>
<script type="text/javascript">
angular.module('app', ['firebase']).controller('ctrl', function($firebase, $scope) {
$scope.logs = [];
var fb = new Firebase('https://kato-sandbox.firebaseio-demo.com/');
var ref = new $firebase(fb);
var childA = ref.$child('alpha');
childA.$on('loaded', function() {
$scope.logs.push('alpha loaded');
var childB = ref.$child('bravo');
childB.$on('loaded', function() {
$scope.logs.push('bravo loaded');
})
})
});
</script>
</body>
</html>
Hopefully that will help you narrow the scope of the error, although it's not in itself a resolution.

Related

How to use scope variables in attributes with string

I am new in angularjs. I have a issue scope variable not working in script tag. I had try ng-src but still not working.
script_path variable not working with script.js if I add only {{script_path}} working fine but if I add {{script_path}}/script.js this is not working.
My example code
<html ng-app="myApp">
<head ng-controller='HeadCn'>
<meta charset="utf-8">
<title>test</title>
<script src="js/angular.js"></script>
<script ng-src="{{script_path}}/script.js"></script>
</head>
<body class="container">
<script>
var app = angular.module('myApp', []);
app.controller("HeadCn", function($scope) {
$scope.script_path = "js/";
})
</script>
</body>
</html>
please give me solution how to use scope variable anywhere in controller.
Thanks in advance
Jimbrooism is right, you are getting this error because security concerns are not being handled.
Please read carefully at https://docs.angularjs.org/api/ng/service/$sce
You may need to use other filter as described on that page or you can completely disable sce at config level, which not recommended
use $sce resolve the problem, create a filter for solve this problem
angular.module('myApp')
.filter('trustUrl', function ($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
});
<script ng-src="{{script_path}}/script.js | trustUrl "></script>

Calling function inside AngularJS goes in endless loop

I am new to AngularJS and I was building a sample app. I want to display the result of Google maps response on my web page. Here I pass the sample value, but the page goes on a loop and gives this error: Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
var app = angular.module('myApp', ['ui.bootstrap']);
app.controller('myCon', function($scope, $http) {
$scope.getAddress = function(url){
return $http.get('https://maps.googleapis.com/maps/api/distancematrix/json?origins=Toronto+ON&destinations='+url+'&mode=driving').then(function(response){
return response.rows[0].elements[0].distance.text;
});
};
And this is the HTML page :
<!DOCTYPE html>
<html lang="en" ng-app="myApp" ng-controller="myCon">
<head>
<meta charset="UTF-8">
<title>Angular Demo</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
<script src="js/app.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="page">
{{getAddress('Ottawa')}}
</div>
</body>
</html>
When you invoke a function within interpolation {{xxx()}} you need to be careful. Interpolation runs every digest cycle and you are calling a function within that, All is well, but then within the function you are making an $http call which again triggers a digest cycle (after it has resolved/rejected and every promise chain) and interpolation expression gets evaluated again to stabilize the view. Angular will just go on hoping the view will be stable after every digest cycle, but apparently not. Angular does this loop till an max limit of 10 times (internally set but configurable though it will not solve your problem) internally and stops trying to stabilize displaying the error which you see in your console.
Just make the call when an event is triggered and not sure why exactly you want to do that. But you could as well do it in the controller right away when it is instantiated and bind the data as property to the view. Or bind the function getAddress(url) during a specific event happens (i cant recommend further with the limited knowledge of why you are invoking getAddress('ottava') from the interpolation)
An example, in your view
{{distance.text}}
In the controller:
$scope.distance = {};
//After getAddress definition call it directly from controller
$scope.getAddress('ottava').then(function(text){
$scope.distance.text = text
});

Restangular is not calling the server

I would like to ask some help because I don't know what the problem is in this case.
I have a simple MVC5 application where I want to use angular and restangular. When I load the page the angular controller will be executed but the server is not called. It is just a test method nothing else. The rest service (Webapi2) returns a simple json object.
If I call the webservice by using the browser or Fiddler2 then I get the result what I expect. According to Fiddler the result is json.
When I reload the page I got back nothing, only the promise object, I assume. According to Fiddler there is no server call that time. If I dump out the testResult object (see the TestService.js file below) it contains nothing and I see the there is a property fromServer and the value is false. I assume it indicates whether server communication happened or not.
I went through the restangular documentation but I haven't found anything in it which helps me to get over this case. It doesn't mean that the documentation is wrong. :)
I don't know what is the problem.
The expected json:
{"Id":1,"Name":"Egyeske"}
The single html file (_layout.cshtml)
<!DOCTYPE html>
<html lang="en" ng-app="dilibApp">
<head>
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
</head>
<body>
<div ng-controller="TestController">
Test value: {{testValue}}
</div>
<div>
#RenderBody()
</div>
<div>
<script type="text/javascript" src="~/Scripts/angular.js"></script>
<script type="text/javascript" src="~/Scripts/angular-route.js"></script>
<script type="text/javascript" src="~/Scripts/angular-resource.js"></script>
<script type="text/javascript" src="~/Scripts/restangular.js"></script>
<script type="text/javascript" src="~/Scripts/lodash.js"></script>
#* dilibApp module *#
<script type="text/javascript" src="~/Scripts/AngularModules/dilibApp/dilibApp.js"></script>
<script type="text/javascript" src="~/Scripts/AngularModules/dilibApp/Controllers/TestController.js"></script>
<script type="text/javascript" src="~/Scripts/AngularModules/dilibApp/Services/TestService.js"></script>
</div>
</body>
</html>
The dilibApp.js file:
'use strict';
var dilibApp = angular.module('dilibApp', ['restangular', 'ngRoute', 'ngResource']).
config(function (RestangularProvider)
{
RestangularProvider.setBaseUrl('http://dev.dilib.local/service/webapi/');
});
The TestController.js file:
'use strict';
dilibApp.controller('TestController', function ($scope, testService)
{
$scope.testValue = testService.get();
});
The TestService.js file:
'use strict';
dilibApp.factory('testService', function(Restangular) {
var testResult = Restangular.all('http://dev.dilib.local/service/webapi/test');
//console.log(Restangular);
//console.log(testResult);
return {
get: function() {
//console.log(testResult.one());
return testResult.one();
}
}
});
Document
Restangular.all('link').getList();
Restangular.one('link').get();
So you should put the method .get() after method .one() to get single result or .getList() to get a list of results

Requirejs and external scripts

Hi I have my js application that was built with requirejs. Now I have external page from other developer, he can load his scripts, html, css and other things that not connected to me.
Here example of my module that will be connected to his page:
require(['page', 'widgetGame', 'adDynamic'], function (Page, WidgetGame, AdDynamic) {
function PageExternalGame (params) {
var params = params || {};
Page.call(this, params); // call super constructor.
};
PageExternalGame.prototype.gameLoadingComplete = function() {
alert(111);
};
window.yepiExternalPageGame = new PageExternalGame();
return PageExternalGame;
});
and here example of his page:
<!DOCTYPE HTML>
<html lang="en"><head>
</head>
<body>
<div id='gameArea'>
<canvas id='canvas0' width='480' height='320' style="position: absolute; "></canvas>
</div>
<script data-main="../../YepiMobileNew/UI/js/pageExternalGame" src="http://requirejs.org/docs/release/2.1.14/minified/require.js"></script>
<script src='js/gamemin.js'></script>
<script>yepiExternalPageGame.gameLoadingComplete()</script>
</body>
</html>
So in his page he call my object yepiExternalPageGame, that should be loaded by requirejs. but when he call this object, require itself already loaded, but class pageExternalGame still wasn't loaded, so this object is not exist when he call it. How to handle with it? (His outer scripts also can call my object). Thanks.
Firstly if you sharing your amd app with other it is good to create build that isn't using require.js so you won't force other developers to add another lib and increase page size. You can do this with almond.js
But returning to your question.
Change
<script>yepiExternalPageGame.gameLoadingComplete()</script>
to
<script>
require(['../../YepiMobileNew/UI/js/pageExternalGame'], function() {
yepiExternalPageGame.gameLoadingComplete();
});
</script>
That will help.

sammy.js get handler hiding errors

While using sammy.js library of versions 0.7.4 (also 0.7.1) it was found that if some error happens during execution of get handler function, nothing is printed to console.
For example in the following code snippet nothing will be printed to console though no function with name notExistingFunction exists:
<html>
<head>
...
<script src="/path/to/jquery-1.5.2.min.js"></script>
<script src="/path/to/sammy-0.7.4.min.js"></script>
...
</head>
<body>
<script>
$(document).ready(function() {
var sammy = Sammy(function() {
this.get('#someAnchor', function() {
// this function doesn't exist
notExistingFunction();
});
});
sammy.run();
// this should lead to execution of above handler
window.location.hash = '#someAnchor';
});
</script>
...
</body>
</html>
This really complicates troubleshooting of pages, did someone experienced this as well? Is this expected behavior or a bug? Are there any workarounds for this?
Thanks a lot in advance
Turned out to be easier than I thought - after inspecting sources of sammy.js it was found that somewhy raise_errors flag is set to false by default which manages error reporting.
So, modifying part above code to:
<html>
<head>...</head>
<body>
<script>
...
sammy.raise_errors = true;
sammy.run();
...
</script>
</body>
</html>
starts showing nice errors.

Categories

Resources