Reputation: 272
Im making an android game including an roadmap. (5 worlds, 7 stops each map)
if the level is 3 the user has to animate the walking to stop 3.
I created this svg animation
<animateMotion id="test" begin="0.5s" dur="3s" repeatCount="0" rotate="0" path="{{animate}}" fill="freeze"/>
it works fine until i make an if else function for which scope it should use.(each roadmap has 7 stops/levels, my level is 3 and it scopes world1 so the properties are connected well to the page)
information.once("value", function(snapshot) {
var data = snapshot.val();
if (data.level < 7) {
console.log("world1");
$scope.animate = "M0,0 q225,150 0,200";
}
else if (data.level > 7) {
console.log("world2")
$scope.animate = "M0,0 0,0 0,0";
}
});
i think the problem is that the svg loads before the if else statement is done picking the correct scope.
Is there any way to start the animation using angular? instead of the automatic onload play.
(the information.once and the data snapshot are for firebase where my user data is stored)
Upvotes: 0
Views: 296
Reputation: 40582
To make your above code work, you probably just need to notify the compiler that your values have changed asynchronously. See this post for more about async ops with Angular.
But the best answer here would be to utilize the tools to their full potential and take advantage of the great features Angular and Firebase provide to you for managing these sorts of complex issues. A good read of the docs is a great way to get moving forward with less pain and friction.
You can use routes and the resolve method to avoid timing issues in your views.
Specifically, you would load the data in your route and not render the route until the data has been downloaded. Utilizing AngularFire, you could do this with the $loaded() method.
app.config(function($routeProvider) {
$routeProvider.when("/home", {
controller: "HomeCtrl",
templateUrl: "views/home.html",
resolve: {
// controller will not be loaded until $waitForAuth resolves
// Auth refers to our $firebaseAuth wrapper in the example above
"syncedData": function($firebaseObject) {
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/path/to/data");
return $firebaseObject(ref).$loaded();
}
}
});
});
Now in your controller, you can simply call the injected dependency:
app.controller('HomeCtrl', function($scope, syncedData) {
// guaranteed to be loaded when this controller is rendered
$scope.syncedData = syncedData;
});
You could also make this work with the core Firebase SDK and not use AngularFire, it would simply require that you create a service which returns a promise, and use that in the router instead of $firebaseObject:
app.factory('loadData', function($q) {
return function(ref) {
return $q(function(resolve, reject) {
ref.once('value', function(snap) {
resolve(snap.val());
}, reject);
};
}
});
app.config(function($routeProvider) {
$routeProvider.when("/home", {
controller: "HomeCtrl",
templateUrl: "views/home.html",
resolve: {
// use our new service in the resolve instead
"syncedData": function(loadData) {
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/path/to/data");
return loadData(ref);
}
}
});
});
For one last thought, and another chance to evangelize how reading the docs thoroughly can really encourage powerful usage of an API, if you're using once('value'...) with Firebase, you're likely nullifying all the power of the real-time database by replacing it with a CRUD model. See the guides for some great ways to use Firebase in a real-time paradigm instead.
Upvotes: 2