Issue with can-connect, superMap, fall-through-cache, or some combination of those things

I have a simple model using super map:
models/region.js

let Region = Map.extend({ 
  define:{
    countryCode:{
  }
});

Region.List = List.extend({ Map: Region }, { });

Region.connection = superMap({
  url: {
    getData: `GET ${apiBaseUrl}/{countryCode}/regions`
  },
  Map: Region,
  List: Region.List,
  name: 'region'
});
export default Region;

There is a fixture for that getData url, and there is a log at the top of the fixture to know when it runs.

I’m using that model in a component’s viewModel:
components/select-region/viewmodel.js

import Map from 'can/map/';
import 'can/map/define/';
import {getAppState} from "@src/util/app-state";
import RegionModel from '@src/models/region';

export default Map.extend({
  define: {
    regions: {
      value: [],
      get: function (lastVal, resolver) {
        console.log("select-regions.vm.regions.get - before promise");

        let appState = getAppState(),
            dataSet = {
              baseSiteId: appState.attr('baseSiteId'),
              countryCode: appState.attr('country'),
              userId: appState.attr("userId"),
              lang: appState.attr('lang')
            },
            dataPromise = RegionModel.get(dataSet);

        dataPromise.then((data) => {
          console.log("select-regions.vm.regions.get - promise.then",data);
          resolver(data);
        });

        resolver([]);
      }
    },
    //... other stuff ...//
  }
});

Cool… I then have a way of changing the appState’s countryCode.
somewhere-else.js

//something happens to call:
appState.attr("countryCode", "someNewCountryCode")

What happens is, upon page load, the order of console logs is this:

  1. select-regions.vm.regions.get - before promise
  2. getData fixture
  3. select-regions.vm.regions.get - promise.then

However, when I change the appState’s countryCode, the order of the console logs is this:

  1. select-regions.vm.regions.get - before promise
  2. select-regions.vm.regions.get - promise.then
  3. getData fixture

And finally, things work as expected (the console logs are in the correct order after changing the appState’s countryCode) if I comment out the following in can-connect’s superMap:

behaviors.push("fall-through-cache");

The localStorage value after page load is:

{
  regionCache/instance/undefined: "{"regions":[{"isocode":"US-AL","name":"ALABAMA"}, {"isocode":"US-WY","name":"WYOMING"}]}", length: 1
}

…any thoughts on why the data promise resolves before the fixture runs, why commenting out the fall-through-cache fixes it, or why the localStorage says undefined in the regionCache key?

So my issue was mainly that I was using getData for a list-related endpoint. The server response data is also returning an object with key of “regions” whose value is the list I want and the getListData prefers to have that key called “data”.

the server is responding with:

{
  regions: []
}

and what I need is:

{
  data: []
}

This issue was solved by the following:

  • change getData to getListData in the model
  • set the parseListProp to “regions”
  • be sure to provide ‘idProp’ to the superMap
1 Like