Im trying to update the scope after I get the response from Firebase (I am doing it in the app controler part), here is a sample code.
PS I am using AngularFire ,Firebase and Angularjs
Thank You
var app = angular.module("sampleApp", ["firebase"]);
firebase.initializeApp(config);
app.factory("mealMacros", ["$firebaseArray",
function($firebaseArray) {
var dbRef = firebase.database();
var userId = sessionStorage.uid;
var ordersRef = firebase.database().ref('user_info/' + userId + '/orders');
return $firebaseArray(ordersRef);
}
]);
app.controller("MealCtrl", ["$scope", "mealMacros",
function($scope, mealMacros) {
// $scope.user = "Guest " + Math.round(Math.random() * 100);
//tried mealMacros.on.. didnt work
ordersRef.on('value', function(snapshot) {
var orders = snapshot.val();
// Loop and parse order ids here
for (var key in orders) {
var orderId = orders[key]['orderType'];
console.log(orderId);
$scope.products = orderId;
//code not reaching here
}
});
}
]);
ordersRef.on('value', function(snapshot) {
var orders = snapshot.val();
// Loop and parse order ids here
for (var key in orders) {
var orderId = orders[key]['orderType'];
console.log(orderId);
$scope.products = orderId;
//code not reaching here
}
});
First you need to make sure you get data in var orders
Then $scope.products = orderId; you set the same variable in a loop. Maybe $scope.products is an array and you want to push data in it? $scope.products.push(orderId);
Finally, setting a $scope variable inside a .on event, you will need to call $scope.$apply() before the function returns.
ordersRef.on('value', function(snapshot) {
var orders = snapshot.val();
console.log(orders); // make sure there's an array here
for (var key in orders) {
var orderId = orders[key]['orderType'];
$scope.products.push(orderId);
}
$scope.$apply();
});
One last thing, var orderId = orders[key]['orderType']; may not work as expected depending on the structure of your var orders array.
You can try var orderId = key.orderType; if that doesn't work.
Related
I'm trying to pass variable from js to .ejs template file. The values are coming at page first opening but not showing at refresh page. When I log variables, they are seem in console at every refresh.
ejs:
<input type="text" value="<%= userfb.testTarget %>" data-min="<%= userfb.testMin %>" data-max="<%= userfb.testMax %>" data-fgcolor="#157fa2" class="dial ringtarget">
app.js
var query = firebase.database().ref('/doctors/patients/' + request.id + "/testResults");
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var resultData = childSnapshot.val();
var testid= resultData.testid;
console.log("testid:"+testid);
//Setting Test Results
// Loop through users in order with the forEach() method. The callback
// provided to forEach() will be called synchronously with a DataSnapshot
// for each child:
var childData = childSnapshot.val();
console.log(childData.testResultValues);
var testResultValues =[];
for (i in childData.testResultValues) {
testResultValues.push(childData.testResultValues[i].value);
}
userfb.testResultValues=testResultValues;
console.log(testResultValues);
//Getting test informations
var testquery = firebase.database().ref('/doctors/tests').orderByChild("testID").equalTo(testid);
testquery.once("value")
.then(function(snapshot2) {
snapshot2.forEach(function(snapshot2) {
var testData = snapshot2.val();
userfb.testName=testData.testName;
userfb.testMax=testData.limitValues.max;
userfb.testMin=testData.limitValues.min;
userfb.testTarget=testData.normalValues.Female;
console.log("testmax:"+userfb.testMax);
});
});
});
});
Solution:
I divided the return values (as userfb and testInformations) for each firebase query and now working with refresh page.
var query = firebase.database().ref('/doctors/patients/' + request.id + "/testResults");
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var resultData = childSnapshot.val();
var testid= resultData.testid;
console.log("testid:"+testid);
//Setting Test Results
// Loop through users in order with the forEach() method. The callback
// provided to forEach() will be called synchronously with a DataSnapshot
// for each child:
var childData = childSnapshot.val();
console.log(childData.testResultValues);
var testResultValues =[];
for (i in childData.testResultValues) {
testResultValues.push(childData.testResultValues[i].value);
}
userfb.testResultValues=testResultValues;
console.log(testResultValues);
//Getting test informations
var testquery = firebase.database().ref('/doctors/tests').orderByChild("testID").equalTo(testid);
testquery.once("value")
.then(function(snapshot2) {
testInformations = snapshot2.val()
snapshot2.forEach(function(snapshot2) {
var testData = snapshot2.val();
testInformations.testName=testData.testName;
testInformations.testMax=testData.limitValues.max;
testInformations.testMin=testData.limitValues.min;
testInformations.testTarget=testData.normalValues.Female;
console.log("testmax:"+testInformations.testMax);
});
});
});
});
Below is the code i use to query my firebase in search of players whose ids match the numbers in an array:
.controller('mySquadCtrl', ['$scope','$location','$firebaseArray','$firebaseAuth','CommonProp', 'DatabaseService',
function($scope,$location,$firebaseArray,$firebaseAuth,CommonProp, databaseService){
var uid = CommonProp.userUid();
$scope.uid = uid;
$scope.username = CommonProp.getUser();
if(!$scope.username){
$location.path('/welcome');
}
databaseService.users.child(uid).once('value', function(usersSnapshot){
var users = usersSnapshot.val();
var total = users.total;
var team = users.teamname;
$scope.pick = total;
var orderedPlayers = databaseService.players.orderByChild("id");
$firebaseArray(orderedPlayers)
.$loaded(function(loadedPlayers) {
var normalizedPlayers = loadedPlayers.reduce(function(acc, next) { acc[next.id] = next; return acc; }, {});
var selectedPlayers = $scope.pick.map(function(num){
return normalizedPlayers[num];
});
$scope.players = selectedPlayers;
$scope.sum = function(items, prop){
return items.reduce( function(a, b){
return a + b[prop];
}, 0);
};
$scope.totalPoints = $scope.sum($scope.players, 'goals');
$scope.teamname = team;
}, function(err) {
console.log(err);
$scope.players = [];
});
});
$scope.logout = function(){
CommonProp.logoutUser();
};
}]);
If the user is not logged in, the page redirects them to the 'home page'.
My issue is that the $scope.totalPoints result does not update in realtime even though the $scope.players "goal" value does when i change it in the database directly.
IS there a way to make the $scope.totalPoints update in realtime as I change the values to the $scope.players values in the database?
The $loaded promise is only called once: when the initial data has been loaded from the database. It is not called on updates.
To have an auto-updating sum, you'll instead want to extend $firebaseArray. See the AngularFire documentation for an example of extending an array to include a total. For another good example, see the answer to this question.
I am trying to retrieve some data from my firebase database, but the value I get is "undefined".
This is how I save the data to the database:
var database = firebase.database();
database.ref().push({
mainArray: mainArray,
secondArray: secondArray,
listname: listName,
mainLanguage: mainLanguage,
secondLanguage: secondLanguage,
}, function(error) {
if (error){
stopLoader();
showSnackbar("An error has occured! Please try again later.");
}
This is how I read the data, but the value of listname is "undefined":
var database = firebase.database().ref().child('codes');
var codeInput = document.getElementById('mainSearch');
database.on('value', function(snapshot) {
if (!snapshot.hasChild(codeInput.value)) {
codeInput.value = "";
showSnackbar("A list with this code does not exist!<br><br>Please try another one.")
}
else {
var data = snapshot.val();
var listname = data.listname;
console.log(listname);
}
});
This is the value I get from the database:
This is how the data is structured in the database:
I changed my code to this and now it works perfectly. The problem was that i was trying to get the value from the wrong child. Thanks for your help and patience!
var database = firebase.database().ref().child('codes');
var codeInput = document.getElementById('mainSearch');
database.child(codeInput).on('value', function(snap) {
var data = snap.val();
var listName = data.listname;
var mainLanguage = data.mainLanguage;
var secondLanguage = data.secondLanguage;
var mainArray = data.mainArray;
var secondArray = data.secondArray;
});
Is it possible to pass the key of where the data is located as a parameter in function?
For example;
function myfirebasedata(myDivTag, value){
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.on('child_added', function(snapshot) {
var data = snapshot.val();
myDivTag.innerHTML = data.value.age;
});
}
and then I could call this like:
myfirebasedata(divTagAgeJames, James);
myfirebasedata(divTagAgeBob, Bob);
....
....
So for example, when the first instance of the function is run/called myfirebasedata(divTagAgeJames, James);
it should replace the keywords in the reference of firebase code above to;
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.on('child_added', function(snapshot) {
var data = snapshot.val();
myDivTagJames.innerHTML = data.James.age;
});
Update:
You could try one of those:
1.snapshot.child()
ref.on('child_added', function(snapshot) {
var age = snapshot.child(value).val().age;
myDivTag.innerHTML = age;
});
2.bracket notation
ref.on('child_added', function(snapshot) {
var data = snapshot.val();
myDivTagJames.innerHTML = data[value].age;
});
I'm trying to return an object outside of a function. I'm using an Angular JS promise to log the availableProviders when they've been loaded, which is logging correctly to my console.
function getServiceProviders(serviceId) {
var serviceProviders = ref.child('services').child(serviceId).child('providers');
var providers = ref.child('providers');
serviceProviders.on('value', function(snapshot) { // on services.serviceId.providers
var availableProviders = {}; // create empty availableProviders array
snapshot.forEach(function(childSnapshot) { // for each provider in services.serviceId.providers
var key = childSnapshot.key(); // grab each provider's key
providers.on('value', function(snap) { // on providers
if (snap.hasChild(key)) { // if providers has a child that matches the var key above
var item = snap.child(key); // store that child in a var called item
availableProviders[item.key()] = item.val(); // add item to availableProviders array
}
});
}); // rinse and repeat
var defer = $q.defer();
defer.promise
.then(function() {
console.log(availableProviders);
})
defer.resolve();
});
return availableProviders;
}
I want the getServiceProviders() function to return these availableProviders, but I'm getting this error asavailableProviders` isn't defined outside of that function.
ReferenceError: availableProviders is not defined
Is there any way around this. Any help is appreciated. Thanks in advance!
Problem related to Closures in JavaScript, I think you need to move var availableProviders = {}; outside serviceProviders.on('value', function(snapshot) { function will fix your issue.
Code
function getServiceProviders(serviceId) {
var serviceProviders = ref.child('services').child(serviceId).child('providers');
var providers = ref.child('providers');
var availableProviders = {}; // <==made it global
serviceProviders.on('value', function(snapshot) { // on services.serviceId.providers
snapshot.forEach(function(childSnapshot) { // for each provider in services.serviceId.providers
var key = childSnapshot.key(); // grab each provider's key
providers.on('value', function(snap) { // on providers
if (snap.hasChild(key)) { // if providers has a child that matches the var key above
var item = snap.child(key); // store that child in a var called item
availableProviders[item.key()] = item.val(); // add item to availableProviders array
}
});
}); // rinse and repeat
var defer = $q.defer();
defer.promise
.then(function() {
console.log(availableProviders);
})
defer.resolve();
});
return availableProviders;
}