0

(My project is using Emberfire, which is Firebase's integration for Ember. This allows me to either make direct database calls through Firebase, or to just use the built-in model functions in Ember)

I have two models. One is /users and contains extra information about a user(particularly their schoolId). The other model is /schools which under each id holds info such as schoolName/etc. I am trying to display the name of a user's school based on the schoolId attached to their /users information.

My current approach is to use a helper called school-name.js in which I am using only Firebase queries to return the value:

import Ember from 'ember';

export default Ember.Helper.extend({
  firebaseApp: Ember.inject.service(),
  compute(uid) {
    //Firebase Database Ref
    const database = this.get('firebaseApp').database();
    //Find the current user's schoolId
    database.ref('/users/' + uid).once('value').then(function(snapshot) {
        var schoolId = snapshot.val().schoolId;

        console.log("schoolId: " + schoolId);
        //Find the current user's schoolName based on their schoolId
        database.ref('/schools/' + schoolId).once('value').then(function(snapshot) {
          var schoolName = snapshot.val().schoolName;
          console.log(schoolName);
          return schoolName;
        });
    });
  }
});

This will console.log the schoolName without a problem, but it will not display it in the template. My intuition tells me that I have to do something with Ember's and Firebase's promises system, however I have no idea where to start and the docs have not been very helpful yet.

My previous attempt was with a mixture of Firebase and Ember's model system.

model: function() {

        //Get current user's uid
        const uid = this.get('session.currentUser.uid');

        //Inject Firebase Auth
        const auth = this.get('firebaseApp').auth();
        var user = auth.currentUser;

        //Inject Firebase Database
        const database = this.get('firebaseApp').database();

        if (user) {
            // User is signed in.
            var schoolIdRef = database.ref('/users/' + uid).once('value').then(function(snapshot) {
                var schoolId = snapshot.val().schoolId;
                console.log(schoolId);
                // ...
            });
            console.log(schoolId);
            return this.store.query('schools', {
                //Query specific school ID
                equalTo: "0" //SET THIS TO schoolId SOMEHOW
            });
        } else {
            // No user is signed in.
        }

    }

However the template would still not load the information. I also made an attempt at this by using only Ember Store calls, however I did not know what to do about the fact that the query would return an array instead of a single value.

Any help is appreciated!

David Chalifoux
  • 128
  • 1
  • 3
  • 12

2 Answers2

1
  1. First attempt with helper will return Promise. this will be resolved later and you can't use directly in template. I prefer to stay away from helper for this use case.
  2. Your second attempt you can consider findRecord instead query, this will return single record. By the way I used query and firstObject to retrieve first data. In your code, problem is after resolving schoolId consider getting schollName. model always should return result.
model: function() {
        //Get current user's uid
        const uid = this.get('session.currentUser.uid');

        //Inject Firebase Auth
        const auth = this.get('firebaseApp').auth();
        var user = auth.currentUser;

        //Inject Firebase Database
        const database = this.get('firebaseApp').database();

       return database.ref('/users/' + uid).once('value').then((snapshot) => {
            var schoolId = snapshot.val().schoolId;
            console.log(schoolId);
            return this.store.query('schools', {
                //Query specific school ID
                equalTo: schoolId
            }).then((result) => {
                return result.get('firstObject').get('schoolName');
            });
        });
    }
  1. You might consider ember data relationship for user and school model. You might go through this tutorial,

https://www.toptal.com/emberjs/a-thorough-guide-to-ember-data http://thejsguy.com/2016/01/29/working-with-nested-data-in-ember-data-models.html http://andycrum.com/2014/06/02/getting-started-with-ember-data/

Ember Freak
  • 12,918
  • 4
  • 24
  • 54
  • Thanks for the info! Do you know of any other documentation for ember relationships? They seem poorly documented to me(at least it seems difficult to understand at first). Thanks! – David Chalifoux Jan 18 '17 at 02:49
  • 1
    Updated some links for the tutorials. [ember guides](https://guides.emberjs.com/v2.10.0/models/relationships/) will be always up to date with latest release. – Ember Freak Jan 18 '17 at 02:54
0

Many thanks to the great folks helping out on the EmberJS Slack! Thanks to them I got this all sorted out!

It turns out that I just need to understand how promises work.

Final solution:

templates/application.hbs


{{#each model as |school|}}
    {{school.schoolName}}
{{/each}}

routes/application.js

model: function() {
    const uid = this.get('session.currentUser.uid');
    const store = this.store;
    var userInfo = this.store.query('user', {
        equalTo: uid
    });
    return userInfo.then(function(value) {
        var userInfoObject = value.get('firstObject');
        var schoolId = userInfoObject.get('schoolId');
        return store.query('school', {
            equalTo: schoolId
        });
    });
}

If anyone would like me to provide comments/documentation on this just ask!

David Chalifoux
  • 128
  • 1
  • 3
  • 12