Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<link href="https://code.jquery.com/qunit/qunit-git.css" rel="stylesheet" type="text/css" />
<meta name="description" content="CanJS Models">
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
 <div id="qunit"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.js"></script>
<script src="//canjs.com/release/latest/can.jquery.js"></script>
<script src="//canjs.com/release/latest/can.construct.super.js"></script>
<script src="//canjs.com/release/latest/can.map.define.js"></script>
<script src="//canjs.com/release/latest/can.stache.js"></script>
<script src="//canjs.com/release/latest/can.fixture.js"></script>
<script src="https://code.jquery.com/qunit/qunit-git.js"></script>
<script>
var stateStore = can.fixture.store([
  { name: 'California', short: 'CA' },
  { name: 'New York', short: 'NY'}
],{});
  
var cityStore = can.fixture.store([
  { state: 'CA', name: 'Pasadena' },
  { state: 'NY', name: 'Albany' }
],{});
can.fixture({
  'GET /api/states': stateStore.findAll,
  'GET /api/cities': cityStore.findAll,
  'GET /api/restaurants': function(){
    return [{
      _id: 1,
      name: 'Cheese City',
      slug:'cheese-city',
      address: {
        city: 'Casadina',
        state: 'CA'
      }
    }];
  }
});
  
var State = can.Model.extend({
  resource: "/api/states",
  id: "short"
},{});
  
var City = can.Model.extend({
  resource: "/api/cities",
  id: "name"
},{});
  
var Restaurant = can.Model.extend({
  resource: "/api/restaurants"
},{});
  
</script>
</body>
</html>
 
// State, City, and Restaurant models and
// fixtures created in the HTML tab
// Create a ViewModel that makes `cities` depend on the `state`
var RestaurantListVM = can.Map.extend({
  define: {
    // `states` initialized with a promise that resolves
    // to a list of all states.
    states: {
      value: function() {
        return State.findAll({});
      }
    },
    // `state` and `city` are "source" state values, which all other
    // values are derived from.
    state: {
      type: 'string',
      set: function() {
        // Remove the city when the state changes
        this.attr('city', null);
      }
    },
    city: {
      type: 'string'
    },
    // `cities` depends on the value of `state`.
    // If `state` is set, `cities` will be a promise that
    // resolves to a list of all cities for that state.
    cities: {
      get: function() {
        var state = this.attr('state');
        if(!state) {
          return null;
        }
        return City.findAll({ state });
      }
    },
    // `restaurants` depends on the value of `state` and `city`.
    // If both `state` and `city` are set, `restaurants` will
    // return a promise that resolves to a list of all restaurants
    // for that city and state.
    restaurants: {
      get: function() {
        var state = this.attr('state'),
            city = this.attr('city');
        if(state && city) {
          return Restaurant.findAll({
            'address.state': state,
            'address.city': city
          });
        }
        return null;
      }
    }
  }
});
// Test the ViewModel
QUnit.asyncTest("set state, then city, get restaurants", function(){
  var vm = new RestaurantListVM();
  
  // Set the state
  vm.attr('state','CA');
  
  // Make sure we get cities for it
  vm.attr('cities').then(function(cities){
    QUnit.ok(cities.length, "Got cities");
    QUnit.ok(cities[0].attr("state"), "CA", "Got cities for the right state");
    
    // Set the city
    vm.attr("city","Pasadena");
    
    // Make sure we get restaurants for it
    vm.attr("restaurants").then(function(restaurants){
      QUnit.ok(restaurants.length, "Got restaurants");
      QUnit.start();
    });
  });
});
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
justinbmeyerpro
0viewers