Ember data findRecord return value is not the expected record


#1

I am just starting with Ember and picking up javascript again after few years. Have a basic question.

I have a login page - with login route and controller. I have setup an ember cli mirage endpoint to return applicantsinfo data, when calling GET /applicantsinfo/123

this.get('/applicantsinfos/123', () => {
return { applicantsinfo: { "id": 123, "sessionId": 3, "userName": 'Abc', "salary": '10110', "age": '1100', "password": 'password03' } }
});


import Ember from 'ember';

 export default Ember.Controller.extend({
   applicantsinfoRecord: '',
   userName: '',
   password: '',
  actions: {
  submitAuthForm() {
  const userName = this.get('userName');
  const password = this.get('password');

 // call to mirage 
 this.get('store')
.findRecord('applicantsinfo', userName)
.then((applicantsInfoRecord) => {
  this.set('applicantsInfoRecord', applicantsInfoRecord);
  console.log('inside then function',applicantsInfoRecord);  
  this.transitionToRoute('form-edit');
})
.then((error) => {
  console.log('then error happened', error);
  this.set('submissionMessage', 'then(error): There was an error logging in with userName:', userName);
})
.catch((error) => {
  console.log('inside catch', error);
  this.set('submissionMessage', 'catch(error): There was an error logging in with userName:', userName);
});

}} });

login.hbs is simple with username/password fields and submit button that calls the controller submitAuthForm() function

<label>Card Number</label>
   {{input type="text" value=userName}}


<label>Password</label>
 {{input type="text" value=password}}

<button class="primary-link" type="submit" {{action 'submitAuthForm'}}>
  Submit
</button>  

my problem is when the findRecord call returns the value in the then() block, it gives me an ember class

It should return me an actual applicantinfo record. that is returned by cli mirage

Basically I want to set this returned object applicantsinfo in controller property and then transition to the next page form-edit, where i will retrieve this property, using

this.controllerFor('login').get('applicantsinfo')

So essentially i have two questions, should i not get at that applicantsinfo record instead of ember _Class variable.

Also is this a correct approach to call for authentication first, if its successful, i will probably pass the sessionId from the return applicantsInfo record over to the next page, where in the route (in the model() function) , i can make another back-end call to pull additional customer profile based on the sessionId.

Please note that i am not asking how to write authentication functionality. This question can be generalized to a case - where first screen’s controller makes a back-end call, retrieves a sessionId from the returned result, and then transitions to the next page, where the route for that page, makes another backend call based on the sessionId passed from previous page’s controller.


#2

i looked at this suggested answer, its very close but not exactly what i am looking for.

My issue is I do need to make a backend call in login controller , get the applicantsinfoRecord, obtain the sessionId from it and then transition over to the next form-edit page, where i will make another call to the back-end based on the sessionId to pull the customer profile. Just mentioning this detail, so that my question does not get flagged as a duplicate to the above mentioned post.


#3

findRecord() returns a Model class. You’ll need to use property getters on the object passed in the then(). There is a pretty good intro here:

https://emberjs.com/api/ember-data/2.14/classes/DS.Store


#4

Hi Chris, i have tried doing that, I get undefined back

console.log('inside then function',applicantsInfoRecord.get('sessionId'));  

the result of above statement is “inside then function undefined” in the console.

anything else i can try… ?


#5

What does your model definition look like?


#6

from within following controller controller code, when GET /applicantsinfo/123 endpoint is hit

ember-cli mirage returns the following applicantsinfo object

this.get('/applicantsinfos/123', () => {
        return { applicantsinfo: { "id": 123, "sessionId": 3, "userName": 'Abc', "salary": '10110', "age": '1100', "password": 'password03' } }
      });

so that’s the model object i want to print out using console.log within my controller code.


#7

@leofoto123 mirage is returning JSON, but then Ember Data is serializing that JSON into a record object of type DS.Model, which is what you are logging. If you want to log the JSON I believe there’s a method on a Model record called .toJSON which will convert that record to JSON for you. Note that in Ember Data dealing with those record objects is the expected way to interact with your model data. Converting to JSON should probably only be done for logging/debugging purposes.


#8

Ahh. You’ll be in good shape. You are missing a Model class. Look in the guides, it is right there up front. I am somewhat surprised that Ember obliged your findRecord call without it, but I’ve never tried. You will need to spell out to Ember Data which fields within your JSON you are willing to keep. On the one hand, it is kind of a pain in the butt to have to have to create such a thing, because your programmer-brain already intuited that it is not necessary. But on the other hand, it is one of niftier things about Ember Data. Some APIs return globs of un-interesting data, and it is nice to only have ED keep the fields you want. Additionally, the formal definition allows for the change-notification plumbing that makes Ember so wonderful.


#9

when i do applicantsinfoRecord.toJSON(), it gives me JSON representation of ember DS.Model object.

That’s not what I need. What I need is, the applicantsInfo object that contains my JSON

applicantsinfo: { "id": 123, "sessionId": 3, "userName": 'Abc', "salary": '10110', "age": '1100', "password": 'password03' }

What i want to do is

  1. in the login controller, get the sessionId out from this applicantsinfo object
  2. transition to the form-edit page
  3. on form-edit page i want to make a call to another backend service based on the sessionId from the login controller, that will populate the model for form-edit route.

am i taking a wrong approach here ?


#10

So the record is empty. So either your Ember model is set up incorrectly, your serializer is set up incorrectly, or mirage is set up incorrectly. Could you post your model definition (project/models/applicantsInfo.js), your serializer (if you have one, either application serializer or applicatsInfo serializer), and describe your mirage setup a little more (what version, do you have a model? serializer? just a fixture in your config.js?)…?

I’m not really sure you want/need Ember data here at all though. I typically try to avoid using ED for anything that involves authentication or passwords, etc. Perhaps you should just use a raw ajax request like:

Ember.$.ajax(...)
.then(...)
.error(...)

#11

Hi dknutsen, thanks for your response,

the problem was infact my model class which had its fields disabled (during some debug session and i forgot to turn them back on), so the console.log(applicantsinfo.get('userName) statement (when i tried initially) kept on giving me undefined. now when i fixed my model to include the relevant fields it is actually giving me the value back.

For the sake of completeness, one should also make sure the returned value from ember-cli-mirage should have matching serializer selected as well in the app/mirage/serializers/application.js

For JSON API compliant responses, keep the default, JSONAPISerializer. For simple JSON responses (that’s my case), use the RestSerializer instead to avoid any issues.

I am glad it did turn out to be a newbie mistake issue, not something that Ember framework is not handling nicely.

Thanks everyone for your help. Much appreciated.