MOLEDesign
MOLEDesign

Reputation: 488

AngularFire - Array of Arrays not being injected into Firebase

I have a production system that successfully injects data into Firebase from an AngularJS app. However I have an issue with a particular type of record which contains and array of arrays.

here is a prettified graphic of the record.

enter image description here

What happens is when I do

$scope.service.$add($scope.service);

where $scope.service is the entire record, it loses the locations[] array of arrays. The delayReason array goes in no problem.. but the locations is ironically the critical data

Is there a simple way to inject this record into Firebase without having to rewrite it and then inject.. though to be honest, my prefered method of injection would be to have a single record for each location which incorproates the data in the 'root' of $scope.service

EDIT : My final solution, using knowledge from one answer and an example from the other

$scope.addTodo = function (data) { getDetail();

  $scope.service.callingPoints=[];
  for (var i = 0, len = $scope.service.locations.length; i < len; i++) {
      if($scope.service.locations[i].crs) {
          crsValue = $scope.service.locations[i].crs
      } else {
          crsValue = '';
      }
      if($scope.service.locations[i].std) {
          stdValue = $scope.service.locations[i].std
      } else {
          stdValue = '';
      }
      if(stdValue && crsValue) {
          $scope.service.callingPoints.push({
              crs: crsValue,
              std: stdValue
          });
      };
  }
  $scope.todos.$add($scope.service);

Basically I rewrite the array (this is only a partial answer, the final array is much bigger) removing any null values

Upvotes: 0

Views: 56

Answers (2)

SteamDev
SteamDev

Reputation: 4414

In JavaScript terms, delayReason is an object (associative array) and locations is a regular array (indexed array).

Firebase works best with objects (key/value pairs); as this format allows for direct paths to specific data points.

/path/to/record/delayReason/value points directly to 896

Solution:

Restructure your JSON to pass locations as an object vs. an array

{
  "locations": {
    "xxx": {
      "uid": "xxx",
      "name": "Location 1"
    },
    "yyy": {
      "uid": "yyy",
      "name": "Location 2"
    },
    ...
  }
}

Arrays should generally be avoided in Firebase, because:

...the indices used to reference each record are fluid and change over time.

For more on best practices: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

Upvotes: 1

Gabriel Barreto
Gabriel Barreto

Reputation: 6421

Is this 0 to 11 different locations?

What you can do is in your JSON - before set/push/update it to firebase - is to create a key for every location in it.

So if you're doing something like:

for(var i = 0; i < length; i++){
  myJson.locations.push(location)
}

you can do instead:

for(var i = 0; i < length; i++){
  // HERE YOU USE THE KEY YOU WANT, GENERATE ONE, HARD CODE ONE, WHAT YOU WANT.
  // IF IT'S HARD CODED YOU CAN USE THE NAME INSIDE A ' '.
  myJson.locations[location.name] = { 
    lat: lat,
    long: long,
    uid: uid,
    etc: etc
}

And them you set that JSON into firebase.

If there's a fixed number of itens, like it'll always be 11 or a small number, you can iterate and push every location, so te push method generates a random key.

for(var i = 0; i < length; i++) {
  firebase.database().ref('Database/JSON/LOCATION).push(JSON[i]).then(...);
}

But i honestly prefer the first approach.

Hope it helps :)

Upvotes: 1

Related Questions