1

I'm using Backbone.js and StackMob for a mobile app, and have run into a strange problem that I can't get my head around. According to the StackMob docs, StackMob.Model extends Backbone.Model, and thus has access to the same methods, and should work the same way. As I understand it, it's a simple swap to make.

Here's the situation:

I have a collection that's being populated by an API call to FourSquare, which is being rendered out into the view as a list. Each model in the list is rendered with a data-id attribute:

    $("ul#resultsList").append("<li class='result' data-id='" + place.get('id') + "'><span class='listingName'>" + place.get("name") + "</span><span class='listingDetail'>" + place.get("location")["address"] + "</span><span class='listingDetail'>" + place.category + "</span></li>");

(The above code is what's looped through to build the list).

The list shows up fine, and everything on that end works as it should. Then, I have the following attached to the click event on each list item:

saveItem: function(e) {
    window.item = $(e.currentTarget).data("id");
    window.newplace = this.collection.get(window.item);
    console.log("New place: "+ window.newplace); //shows the model in Backbone, undefined in StackMob
    App.navigate("#add", {
        trigger: true
    });
},

This code basically looks at the item clicked, goes and gets the ID, then looks up that model in the collection based on the ID and stores it into window.newplace.

Then, the app navigates over to #add, which instantiates the view with window.newplace as the model:

addItem: function() {
    if (!window.newplace) {
    window.newplace = new Place({});
    }
    this.changePage(new AddItemView({model:window.newplace}), "slide");
},

Here's the problem:

This works exactly as it should when the Place model is set up as a Backbone.Model. As soon as I switch it to StackMob.Model, it shows window.newplace as undefined.

I can't imagine why switching these should make any bit of difference, but it seemingly does.

Just for the sake of full clarification, here's the model when using Stackmob.Model:

window.Place = StackMob.Model.extend({
...
});

Any ideas? If it didn't work at all, I'd chalk it up to some really stupid thing, but since it works fine extending Backbone, but not StackMob, I'm really confused.

Thanks!

Justin Davis
  • 305
  • 1
  • 3
  • 16
  • So you're saying the `new Place({})` is yielding `undefined` when `Place` extends `StackMob.Model` but a useful object when `Place` extends `Backbone.Model`? – mu is too short Nov 30 '12 at 00:37
  • Not exactly (although kind of along those lines). If I try to run `new Place({})` when Place extends `StackMob.Model`, it will work. However, I have a collection of places (`StackMob.Collection` called "Places") where the model is `Place`. When I try to get one of the models from that collection and store it into a variable, it doesn't work with StackMob, but does with Backbone. – Justin Davis Nov 30 '12 at 00:45
  • Or is it `this.collection.get(window.item)` that's supposed to initialize `window.newplace`? – mu is too short Nov 30 '12 at 00:47
  • Yeah, that's exactly it. – Justin Davis Nov 30 '12 at 00:48
  • Have you checked that `e.currentTarget` and `window.item` are what you're expecting them to be? Are you certain that `this.collection` has been fetched and populated? – mu is too short Nov 30 '12 at 01:03
  • Yeah, I'm logging all that to the console. `window.item` returns the correct model ID, regardless of what `Place` is extending. It's the next step after that, where I call `this.collection.get(window.item)` where it's failing. With Backbone, it gets the correct object from the collection and stores it. With StackMob, it fails. – Justin Davis Nov 30 '12 at 01:27

2 Answers2

1

You need to call StackMob.init(..) first before using StackMob.Model, StackMob.Collection and other StackMob items.

Your external script is likely being executed before you call StackMob.init(..).

Hope that helps!

Erick

Erick Tai
  • 264
  • 1
  • 6
  • Erick, thanks. I'm actually calling StackMob.init at the very top of the document (in index.html). I know it's working, because I can successfully instantiate and save a `User` using StackMob... – Justin Davis Nov 30 '12 at 00:58
1

Ok, I figured out a workaround for this problem.

Here's the deal. When I was calling this.collection.get(window.item), I was looking for the ID property on the Place object being clicked (since I'm passing that ID into the URL, it's easy to retrieve on click).

With Backbone, that ID was showing up as a root property of the object, at place.id. With StackMob, for whatever reason, it wasn't. It was stored in the Attributes object inside Place (as if you'd called place.set("id")).

So, when I went looking to get it by ID, StackMob was looking for the root property "id" on the object, not finding it, and returning "undefined".

By putting this.id = this.get("id") in the initialization of the model, I was able to get it to the root and successfully retrieve the model.

I'm still unsure why that ID was being set at the root with Backbone, but not StackMob, but regardless, at least there's a solution.

Justin Davis
  • 305
  • 1
  • 3
  • 16