realph
realph

Reputation: 4671

Update Item from Firebase

I'm trying to work out how to update an item that is stored in my Firebase. I've managed to get it to a point where I can create and remove items. I'd now like to edit and update an existing item. My items are repeated on the page, and each of them have an "Edit" button next to them.

HTML

<form>
  <input type="text" placeholder="Enter title here" ng-model="editedProvider.title">
  <button type="submit" ng-click="updateProvider(provider.name)">Submit</button>
</form>

I'm adding items to my list like so:

JS

$scope.newProvider = {};
$scope.providers = [];

providersRef.on('child_added', function(snapshot) {
  $timeout(function() {
    var snapshotVal = snapshot.val();
    $scope.providers.push({
      title: snapshotVal.title,
      name: snapshot.name()
    });
  });
});

// Create Item
$scope.createProvider = function() {
  var newProvider = {
    title: $scope.title,
  };
  providersRef.push(newProvider);
};

I can't work out how to update this item. I've got an update provider function that looks like this:

$scope.updateProvider = function(name) {
  providersRef.child(name).update({
    title: snapshotVal.title
  });
};

But that shows this error in the console:

Error: Firebase.child failed: First argument was an invalid path: "undefined". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"

I've tried creating a function that finds the uses the snapshot.name() to check it against the item I'm editing to update the title with the new value, but it doesn't seem to work.

Any idea what I'm doing wrong?

I've set up a Plunker over here. Any help with what I'm doing wrong is appreciated.

Upvotes: 0

Views: 155

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598623

The relevant HTML from your view is this:

  <div ng-show="shouldShowEditing()">
    <h3>Editing {{ editedProvider.title }}</h3>
    <form role="form" name="addPlaceForm">
      <div class="form-group">
        <input type="text" placeholder="Enter title here" ng-model="editedProvider.title">
      </div>

      <div class="form-group">
        <button type="submit" class="btn btn-primary btn-lg" ng-click="updateProvider(provider.name)">Submit</button>
      </div>
    </form>
    <button type="button" class="btn btn-default" ng-click="cancelEditing();">Cancel</button>
  </div>

The relevant code is this:

$scope.updateProvider = function(name) {
  console.log('updateProvider: '+name);
  providersRef.child(name).update({
    title: snapshotVal.title
  });
};

I added that console.log statement, because it shows you easily what is going wrong. The output is:

updateProvider: undefined

So from that you can see that you're not passing in the provider's name correctly. With this knowledge, you can go back to the HTML and see that you're refering to provider.name in there, where the rest of that form refers to editedProvider.

So the fix is:

<button type="submit" class="btn btn-primary btn-lg" ng-click="updateProvider(editedProvider.name)">Submit</button>

Update

With the name-passing problem solved, the next error message is:

ReferenceError: snapshotVal is not defined

Which is also quite clear: your updateProvider code looks copy/pasted from one of the Firebase listeners and is referencing a non-existant snapshotVal. Instead, it should be getting the new title from the Angular scope:

$scope.updateProvider = function(name) {
  providersRef.child(name).update({
    title: $scope.editedProvider.title
  });
};

Upvotes: 1

Related Questions