knockout-observable-promise

0.7.0 • Public • Published

knockout-observable-promise

Easily wire up promises to knockout

Build Status

Working with data from our server, we often want to show loading status or want to chain other work dependent on an asyncrounous task. knockout-observable-promise is observable extender that will wire up to a promise automatically if it is assigned one.

Examples

var name = ko.observable(),
    age = ko.observable(),
    user = ko.observable()
 
ko.applyBindings(document.body, {
  name: name,
  age: age,
  user: user,
 
  findUser: ko.computed(function() {
    if (name() && age()) {
      return $.get({
        url: '/users/search', 
        data: {
          name: name(),
          age: age()
        }
      }).then(function(resp) {
        user(resp.data)
      })
    } else {
      return $.Deferred().promise()
    }
  }).extend({ throttle: 100, promise: true })
})

View:

<style>.loading { background-image: url(loading.gif); }</style> 
<form>
  <h1>Search for a person</h1>
  <label for="name">Name</label>
  <input name="name" data-bind="value: name"></input>
  <label for="age">Age</label>
  <input name="age" data-bind="value: age"></input>
 
  <div data-bind="css: { loading: findUser().state() === 'pending' }">
    <!-- ko if: $root.user() -->
      <p data-bind="text: 'found user ' + $root.user().username">
    <!-- /ko -->
  </div>
  <p class="error" data-bind="visible: findUser().state() === 'rejected'">An error occoured looking for that user!</p>
</form>

You can optionally have the observable convert to the resolve or rejected value if that is convient to you

var name = ko.observable(),
    age = ko.observable
 
ko.applyBindings(document.body, {
  name: name,
  age: age,
 
  user: ko.computed(function() {
    return lookupUser(name(), age())
  }).extend({ throttle: 100, promise: { convert: true } })
})

View:

<style>.loading { background-image: url(loading.gif); }</style> 
<form>
  <h1>Search for a person</h1>
  <label for="name">Name</label>
  <input name="name" data-bind="value: name"></input>
  <label for="age">Age</label>
  <input name="age" data-bind="value: age"></input>
 
  <div data-bind="css: { loading: user() && user().state && user().state() === 'pending' }">
    <!-- ko if: $root.user().username -->
      <p data-bind="text: 'found user ' + $root.user().username">
    <!-- /ko -->
  </div>
  <p class="error" data-bind="visible: user() && user().state && user().state() === 'rejected'">
    An error occoured looking for that user!
  </p>
</form>

Differences from ko.promise

ko.promise intends to make observables and promises the same object, letting you use them interchangably for cases when you do have one asyncrounous operation to model. That's not the goal of knockout-observable-promise - the observable is not a promise, nor does it have to be, and it can assigned new promises that are wired up again in the future, whereas ko.promise cannot since once a promise is resolved or rejected, it cannot change - a promise is an async operation, not a pub-sub mechanism. They are different problems, so choose the library that you need.

Package Sidebar

Install

npm i knockout-observable-promise

Weekly Downloads

0

Version

0.7.0

License

ISC

Last publish

Collaborators

  • nathanboktae