Mpondomise Mpondomise - 1 month ago 36
AngularJS Question

AngularJS Firebase database query filter based on other database

I get the values stored in the "projects" field under a current user's data in Firebase database called users:

first method:

var promise = MyUser.user();
promise.then( function onSuccess(user) {
$scope.userprojectskeys = user.projects;
});


second method:

var keyquery = DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("savedprojects").forEach(function(childSnapshot) {
var userprojects = childSnapshot.val();
console.log("my list is :", userprojects );
});
});


the
$scope.userprojectskeys
of the first method and the
userprojects
of the second method both return the data needed:


first method output:


enter image description here


second method output:


my list is : -KUTLAZENGlxtzCtEfaZ
my list is : -KUTLM8r_kmVSTaxzLW5
my list is : -KUTPrs6ARZXjbjtNr7O



On the other hand, I have another function which gets the list of children under another database called projects like the following:


var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo("-KUTPrs6ARZXjbjtNr7O");
$scope.projectslist = $firebaseArray(projectquery);



what I am doing now is ng-repeating the fields of the object in
$scope.projectslist
, displaying the fields for each project.


<tr ng-repeat="obj in projectslist">
<td>{{ obj.field1}}</td>
<td>{{ obj.field2 }}</td>
<td>{{ obj.field3 }}</td>
<td>{{ obj.field4 }}</td>
</tr>


Question :



how is it possible to pass the above list of project keys obtained previously from current user's data (either using first or second method) into the latter function which shows the projects and filters them by key in
equalTo()
?



but as you can see, I am passing one project ID manually to my filter
equalTo
, and it is working. But I need to pass in all of the keys into equalTo.




one proposed method is:



one proposed method is to combine these two functions like this:

$scope.projectslist = [];
DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
$scope.projectslist.push($firebaseArray(projectquery));
});
});


but this is with no success! the table is showing the rows, but no value inside: http://imgur.com/uByHT3c

here is the screenshot of the debugger: http://i.imgur.com/TaDZLlk.png



update:



here is the structure of my
users
child in mydatabase in firebase:

enter image description here

In which you can see five users, and for each user, there are a number of fields, one of which is a field that stores the user projects keys and in this example, the user has four project keys.



and here is the projects child in firebase mydatabase:

enter image description here

here we see the global view of my firebase databse.
So the goal is to look up the projects keys from users and then show the corresponding projects from the projects database, that is ng-repeat the fields of those projects.

update:



here is the console log after Zura's suggestion:

$scope.projectslist = [];
DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
//console.log("loaded. Data: ", userprojects);
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);

var list = ($firebaseArray(projectquery));
console.log("list: ", list);

});
});




each list contains the info I need for each project of the current user. Perfect!
But how to access them and store them in a
$scope
to be able to call it in my html?



enter image description here




update:




I can only show the last project by passing the list into a $scope:

The project shown is the last of the forEach iteration. The question is how can I show all of the iterations of forEach and pass it into an array?

update 25.10.2016:



here is an updated version of the code which concatenates the objects: first one, then the first two together, the first three, and at last all objects concatenated into one big array, see the console log below:

$scope.projectslist = [];

DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);

var list = $firebaseArray(projectquery);

$scope.list = $firebaseArray(projectquery);
console.log("list: ", $scope.list);
list.$loaded(function(){
$scope.projectslist = $scope.projectslist.concat(list);
console.log("loaded: ", $scope.projectslist);
});

});
});




enter image description here

and each object directly contains the info I need as shown in the previous object screenshot.

Answer

Your problem is in the following code.

$scope.projectslist.push($firebaseArray(projectquery));

firebaseArray() returns array and what push method do is that it pushes given parameter at the end of the array. So here, you will have array which contains also arrays.
Instead you want to concat existing array with $firebaseArray(projectquery).

I suggest to try the following code.

var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
var list = $firebaseArray(projectquery);
list.$loaded(function(){
    $scope.projectslist.contact(list);
});

And if you are using angularfire I think you should modify fetching user's projects also using $firebaseObject. And you do not need to use orderByKey because you are fetching only one object.

var user = $firebaseObject(DatabaseRef.ref('/users/' + userId));
user.$loaded(function(){
    console.log("User loaded. Data: ", user);
    angular.forEach(user.projects, function(value, key){
        var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(key);
        // var list = $firebaseArray(projectquery);
        // list.$loaded(function(){
        //    $scope.projectslist = $scope.projectslist.concat(list);
        // });
        // or shortly. Replace 4 lines above with this line.
        $scope.projectslist.push($firebaseObject(projectquery));
    });
});

UPDATE

As you are getting only one list it would be better to try $firebaseObject and get object and push it in array.

UPDATE 25.10.2016:

Now your problem is here.

DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
    .then(function onSuccess(snapshot) {
        snapshot.child("projects").forEach(function (childSnapshot) {

This is not done according my suggestion. You are NOT using angularfire and html is NOT automatically recompiled. You should call $scope.$apply at the end of onSuccess promise or better... You should use angularfire approach - $firebaseObject which automatically calls $scope.$apply.

var user = $firebaseObject(DatabaseRef.ref('/users/' + userId));
user.$loaded(function(){
    console.log("User loaded. Data: ", user);
    angular.forEach(user.projects, function(value, key){
Comments