Season
Season

Reputation: 73

Firebase Ionic Nested Search

I'm trying to make a search function. When a user selects a product, a list of products should be shown belonging to some storage place.

For so far, I can only show the array Products with all the items in it. But when I want to go deeper and loop over each items (to search items that match with the selected item), I got an error:

Error: No index defined for Products

This is my code:

controllers.js:

.controller('InventoryCtrl', function($scope, Category, Inventory) {
$scope.categories = Category;


$scope.searchInventory = function(category){
var word = category.Category;
//console.log(word);


var ref = new Firebase('https://vivid-heat-2430.firebaseio.com/');
var invenRef = ref.child('Inventories');
var prodRef = invenRef.child('Products');


invenRef.orderByChild("Products").on("child_added", function(snapshot) {
  var data = snapshot.val();
  var store = data.Inventory;
  var prod = data.Products;
  console.log(prod);


  snapshot.forEach(function(childSnapshot) {
    var test = childSnapshot.val();
    console.log(test);
    //var key = childSnapshot.key();
    //console.log(key);
  });

});
};
})

I’ve already defined my index. But I still got this error.

I also tried it like this in my controller:

$scope.searchInventory = function(category){
var word = category.Category;

var ref = new Firebase('https://vivid-heat-2430.firebaseio.com/');
var invenRef = ref.child('Inventories');
var prodRef = invenRef.child('Products');

invenRef.orderByChild("Products").equalTo(word).on("child_added", function(snapshot){
  console.log(snapshot.key());
});
};
})

Here I got no errors, But I can't log anything to see.

This is my firebase structure:

Database structure

Can you please point out what I did wrong? I'm still new to this and trying to learn from my mistakes.

Thanks in advance!

EDIT

My rules.json

{
"rules": {
    ".read": true,
    ".write": true,
    "Inventories": {
    ".indexOn": "Products"
    }
}
}

JSON file of db structure:

{
  "Categorie" : {
    "-K5a3iGlgi7PS0m3O4y8" : {
      "Category" : "IQ 33cl BOX",
      "Optional" : false,
      "Size" : "24"
    },
    "-K5a3vNZRc2Cur9964Xs" : {
      "Category" : "CL 33cl BOX",
      "Optional" : true,
      "Size" : "24"
    },
    "-K5a40Q79SCqWqMbqWQu" : {
      "Category" : "IQ 33cl CASE",
      "Optional" : true,
      "Size" : "24"
    },
    "-K5a464FON4qdnqE9rgf" : {
      "Category" : "CL 33cl CASE",
      "Optional" : false,
      "Size" : "24"
    },
    "-K5a4TAzHE8cRGPbNeij" : {
      "Category" : "Empty CASES",
      "Optional" : false,
      "Size" : "24"
    }
  },
  "Inventories" : {
    "17-12-2015Storage 1" : {
      "Date" : 1450366396979,
      "Inventory" : "Storage 1",
      "Products" : {
        "CL 33cl BOX" : {
          "boxes" : 0,
          "full" : 11,
          "half" : 13
        },
        "IQ 33cl BOX" : {
          "boxes" : 0,
          "full" : 60,
          "half" : 0
        }
      }
    },
    "17-12-2015Storage Deb" : {
      "Date" : 1450367128198,
      "Inventory" : "Storage Deb",
      "Products" : {
        "IQ 33cl CASE" : {
          "boxes" : 0,
          "full" : 2,
          "half" : 14
        }
      }
    }
  },
  "Storages" : {
    "-K5a4esu-1Na1hkKMP47" : { "name" : "Storage 1" },
    "-K5a4ihb9L5z6qSqQxAx" : { "name" : "Storage Deb" },
    "-K5a4l9odWuPUJJuN8OR" : { "name" : "Storage Bart" },
    "-K5a4nsc47N3k_hMVl2h" : { "name" : "Storage Debosz" }
  }
}

index.html

<div style="max-height: 300px" ng-controller="InventoryCtrl">
      <ion-list>
        <ion-radio ng-repeat="category in categories" class="item-accordion" ng-model="checked.check" value="{{category.Category}}" ng-click="searchInventory(category)">
          <p>{{category.Category}}</p>
        </ion-radio>
        <br>
      </ion-list>

    </div>

Upvotes: 0

Views: 489

Answers (2)

Season
Season

Reputation: 73

I've solved the problem by using Object.keys() to get the name of the products.

I also used a for loop to search for the matching product.

My controller looks like this now:

.controller('InventoryCtrl', function($scope, $firebaseObject, Category, Inventory) {

$scope.categories = Category;

$scope.searchInventory = function(category){
var word = category.Category;

var ref = new Firebase('https://vivid-heat-2430.firebaseio.com/');

var invenRef = ref.child('Inventories');
var prodRef = invenRef.child('Products');

var test22 = [];

invenRef.orderByChild("Products").on("child_added", function(snapshot) {
  var data = snapshot.val();
  var store = data.Inventory;
  var test = Object.keys(prod);

  for( var i = 0; i < test.length; i++){
    if (test[i] == word) {        
     test22.push(data.Inventory);
    };        
  }; 
  $scope.show = test22;
});
 };
})

Upvotes: 0

Jay
Jay

Reputation: 35648

Your structure (according to the link)

Inventories
  some_node_name_1
    Inventory: xxxx
    Products:
      product_name: "product a"
      product_price: 30
  some_node_name_2
    Inventory: xxxx
    Products:
      product_name: "product b"
      product_price: 50

and your query path

var ref = new Firebase('https://vivid-heat-2430.firebaseio.com/');
var invenRef = ref.child('Inventories');
var prodRef = invenRef.child('Products');

(note prodRef doesn't appear to be used)

So how about:

var ref = new Firebase('https://vivid-heat-2430.firebaseio.com/Inventories');
  ref.orderByChild("Products/product_name").on("child_added", function(snapshot) {
});

And the .indexOn rule should be at the same level as where you do the query (product_name).

Edit with more info:

A nodes key is indexed automatically so you don't need to add .index for the node Products (it's already done). However, you would add a index for a child of Products for example:

{
  "rules": {
    "Inventories": {
        "Products": {
           ".indexOn": ["product_name"]
        }
    }
  }
}

or (I believe this is another option)

{
  "rules": {
    "Inventories": {
       ".indexOn": ["Products/product_name"]
    }
  }
}

Upvotes: 1

Related Questions