0

I am creating an array in JS for my application

$scope.items = [];

When I add an item to the array we pull information from a Firebase Reference and put it into the items array.

es.addItem = function(item){

   var product = $scope.products[item];

   $scope.items.push({
      'sku'     : product.sku,
      'name'    : product.name,
      'pricing' : {
          'cost'   : product.pricing.cost,
          'markup' : product.pricing.markup,
       }

    });
    $scope.newItem = null;
}

Once I am done adding items to the array, I want to be able to save this in Firebase along with the Estimate information that this is all related to.

es.new = function (reference) {

   console.log(angular.toJson($scope.items));

   var estimatesRef = firebaseUrl+'estimates';

   var estimatesListRef = new Firebase(estimatesRef);
   estimatesListRef.push({ 
      'number'     : es.number,
      'created'    : date(),
      'expiration' : FDate(es.expiration),
      'viewable'   : es.viewable,
      'client'     : es.client,
      'author'     : authData.uid,
      'status'     : {
         'viewed'   : '0',
         'approved' : '0',
         'denied'   : '0',
         'expired'  : '0'
       },
       'products'   : angular.toJson($scope.items)
   });

}

Before I started doing angular.toJson($scope.items) the client side would give me an error about invalid items in submission.

This all submits but this is how products are stored in firebase:

"[{\"sku\":\"029300889\",\"name\":\"Test Product\",\"pricing\":{\"cost\":\"10\",\"markup\":\"20\"},\"qty\":\"1\"},{\"sku\":\"4059834509\",\"name\":\"Test Service\",\"pricing\":{\"cost\":\"100\",\"markup\":\"20\"},\"qty\":\"1\"}]"

Clearly not how I am wanting them:

...
{
  sku: '',
  name: '',
  etc....
},
{
  sku: '',
  name: '',
  etc....
},

the $scope.items array while being ran through angular.toJson() console logs out like so:

[{"sku":"029300889","name":"Test Product","pricing":{"cost":"10","markup":"20"},"qty":"1"},{"sku":"4059834509","name":"Test Service","pricing":{"cost":"100","markup":"20"},"qty":"1"}]

Which looks alot like what I need minus the encasing [] Is this what is preventing Firebase from saving this correctly? What would your recommendation be?

(I've thought about while I make the Estimate creating a temporary node on my Firebase to save the items, then retrieving those to save the estimate and then deleting the temporary node. That seems like a long task that shouldn't be necessary though. So it's a last resort.)

moevans
  • 319
  • 2
  • 16

2 Answers2

1

Your code is fine. I even tested that in Plunker http://plnkr.co/edit/Op37gDx5QeRuUQpHM6UC?p=preview

    var todoApp = angular.module("todoApp", []);
todoApp.controller("ToDoCtrl", MyController);

MyController.$injec = ['$scope', '$http'];

function MyController($scope, $http) {

  $scope.items = [];
  $scope.items.push({
    'sku': 'product.sku',
    'name': 'product.name',
    'pricing': {
      'cost': '1',
      'markup': 'AA',
    }
  });

  $scope.items.push({
    'sku': 'product.sku',
    'name': 'product.name',
    'pricing': {
      'cost': '2',
      'markup': 'BB',
    }
  });


  $scope.newItem = null;

  $scope.testDB = function() {
    console.log(angular.toJson($scope.items));

    var estimatesListRef = new Firebase('https://enqpzxf4tll.firebaseio-demo.com/');


    estimatesListRef.push({
      'number': 1,
      'created': new Date().getSeconds(),
      'expiration': 6,
      'viewable': 5,
      'client': 4,
      'author': 3,
      'status': {
        'viewed': '0',
        'approved': '0',
        'denied': '0',
        'expired': '0'
      },
      'products': $scope.items
    });

    console.log('done');


  }

}

the problem more likely lies in the data. things like '$' in the data that you try to save which results in failure of HTTP request creation so you get client error.

I suggest testing your code with dummy values as I did in the Plunker and then put pack real values one by one.Also try doing a $http.post with your data to a fake URL to see if the request can be built.

Arrays are a bit tricky with Firebase, but this code seems to be alright

n00b
  • 1,832
  • 14
  • 25
  • Thank you for taking the time to figure that out! I just did more research and posted an answer. Thank you for the confidence! Glad my code was good. – moevans Jun 07 '15 at 02:10
1

After reading @Braim's answer and possibly gaining more confidence. I had discovered something.

While my code is clean and working, I was still getting an error.

AngularJS does something with the javascript arrays when you use them for ng-repeat. It needs to track your changes to those arrays in your DOM.

It adds a $$hashkey to each array item to know when to change the array.

To avoid this issue when you create in your ng-repeat in the html allow angular to track your array by something already there.

<tr ng-repeat="item in items track by item.sku">
   // More code to display the items //
</tr>

Referencing Answer/Question

http://stackoverflow.com/questions/18826320/what-is-the-hashkey-added-to-my-json-stringify-result
moevans
  • 319
  • 2
  • 16