Matt Berkowitz
Matt Berkowitz

Reputation: 975

Ember: ASync belongs to doesn't seem to resolve

I have the following two models:

models/profile.js

import DS from 'ember-data';

export default DS.Model.extend({
  firstName: DS.attr('string'),
  lastName: DS.attr('string')
});

models/user.js

import DS from 'ember-data';

export default DS.Model.extend({
  profile: DS.belongsTo('profile', {async:true})
});

The user models is loaded by a user service, based on a cookie set by the server when the user authenticates:

services/user.js

import Ember from 'ember';

export default Ember.Service.extend({
    store: Ember.inject.service('store'),
    init: function() {
        var _this = this;
        _this.set('user', null)
        if(Cookies.get('uid')) {
            _this.get('store').findRecord('user', Cookies.get('uid')).then(function(user) {
                console.log(user)
                _this.set('user', user)
            }, function(err) {
                console.warn(err);
                Cookies.remove('uid')
                _this.set('user', null)
            });
        } else {
            _this.set('user', null)
        }
    }
});

The user service is injected into the application controller:

controllers/applications.js

import Ember from 'ember';

export default Ember.Controller.extend({
    user: Ember.inject.service('user')
});

I have some debugging output in my main template

templates/application.hbs

{{#if user.user}}
    <h2 id="title">Welcome to Ember {{user.user}} # {{user.user.id}} # {{user.user.profile}} # {{user.user.profile.firstName}}</h2>
{{else}}
    <h2 id="title">Please Log In <a href="/auth/linkedin">Linkedin</a></h2>
{{/if}}

{{outlet}}

which when I authenticate and load the page outputs

Welcome to Ember <project@model:user::ember418:5663bfe19d78ce048784a098> # 5663bfe19d78ce048784a098 # <DS.PromiseObject:ember419> #

I can see requests made to my api endpoints in the console, first for the user then for the profile, as expected:

http://localhost:3000/api/users/5663bfe19d78ce048784a098

{
    links: {
        self: "http://localhost:3000/api/users/5663bfe19d78ce048784a098"
    },
    data: {
        id: "5663bfe19d78ce048784a098",
        type: "users",
        attributes: {
            providers: [{
                provider: "linkedin",
                id: "ECixxxxqc9",
                displayName: "John Smith",
                name: {
                    familyName: "Smith",
                    givenName: "John"
                }
            }]
        },
        links: {
            self: "/users/5663bfe19d78ce048784a098"
        },
        relationships: {
            profile: {
                data: {
                    type: "profiles",
                    id: "5663c05f5fd3331387307e89"
                }
            }
        }
    }
}

http://localhost:3000/api/profiles/5663c05f5fd3331387307e89

{
    links: {
        self: "http://localhost:3000/api/profiles/5663c05f5fd3331387307e89"
    },
    data: {
        id: "5663c05f5fd3331387307e89",
        type: "profiles",
        attributes: {
            active: true,
            yearsExperience: 9,
            lastName: "Smith",
            firstName: "John"
        },
        links: {
            self: "/profiles/5663c05f5fd3331387307e89"
        }
    }
}

It seems like the user.user.profile promise isn't being resolved, hence the <DS.PromiseObject:ember419> output and no value for user.user.profile.firstName. Is there something I'm missing in the model definitions or is there something I need to call to manually tell the controller/template that a belongsTo has been resolved?


Updates: I tried to add a reference from profile to user, however the results are the same

For reference,

new /models/profile.js

import DS from 'ember-data';

export default DS.Model.extend({
  user: DS.belongsTo('user'),
  firstName: DS.attr('string'),
  lastName: DS.attr('string')
});

new http://localhost:3000/api/profiles/5663c05f5fd3331387307e89

{
    links: {
        self: "http://localhost:3000/api/profiles/5663c05f5fd3331387307e89"
    },
    data: {
        id: "5663c05f5fd3331387307e89",
        type: "profiles",
        attributes: {
            active: true,
            yearsExperience: 9,
            lastName: "Smith",
            firstName: "John"
        },
        links: {
            self: "/profiles/5663c05f5fd3331387307e89"
        },
        relationships: {
            user: {
                data: {
                    type: "users",
                    id: "5663bfe19d78ce048784a098"
                }
            }
        }
    }
}

Upvotes: 4

Views: 269

Answers (1)

Matt Berkowitz
Matt Berkowitz

Reputation: 975

It seems my problem is not what I think it is...

I added a "first" attribute to profile and it works fine, it seems that all attributes that are in camelCase aren't getting populated, which is another issue

model with "first", /models/profile.js

import DS from 'ember-data';

export default DS.Model.extend({
  user: DS.belongsTo('user'),
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  yearsExperience: DS.attr('number'),
  active: DS.attr('boolean'),
  first: DS.attr('string')
});

endpoint with "first", http://localhost:3000/api/profiles/5663c05f5fd3331387307e89

{
    links: {
        self: "http://localhost:3000/api/profiles/5663c05f5fd3331387307e89"
    },
    data: {
        id: "5663c05f5fd3331387307e89",
        type: "profiles",
        attributes: {
            active: true,
            yearsExperience: 9,
            lastName: "Smith",
            firstName: "John",
            first: "John!"
        },
        links: {
            self: "/profiles/5663c05f5fd3331387307e89"
        },
        relationships: {
            user: {
                data: {
                    type: "users",
                    id: "5663bfe19d78ce048784a098"
                }
            }
        }
    }
}

updated /templates/application.hbs

{{#if user.user}}
    <h2 id="title">Welcome to Ember {{user.user}} # {{user.user.id}} # {{user.user.profile}} # {{user.user.profile.firstName}} # {{user.user.profile.first}}</h2>
{{else}}
    <h2 id="title">Please Log In <a href="/auth/linkedin">Linkedin</a></h2>
{{/if}}

{{outlet}}

renders as

Welcome to Ember <prohacvice@model:user::ember428:5663bfe19d78ce048784a098> # 5663bfe19d78ce048784a098 # <DS.PromiseObject:ember427> # # John!

This indicates to me that the issue isn't with the belongsTo resolving, but rather some values (the ones with camelCase) not being properly set. I'll do some research into that and if necessary post an appropriate question for it

Upvotes: 1

Related Questions