EmberJS no model was found but it's there - javascript

I'm writing an ember-cli app. I have the following model:
// app/models/school.js
export default DS.Model.extend({
name: DS.attr('string', { defaultValue: '' })
});
It was generated using an ember generator like all my other models. It has a functioning unit test as well that tests for the default value of it's name attribute. All tests are green until another model belongs to school like this:
// app/models/professor.js
export default DS.Model.extend({
name: DS.attr('string', { defaultValue: '' }),
email: DS.attr('string', { defaultValue: '' }),
courses: DS.hasMany('course'),
posts: DS.hasMany('post'),
school: DS.belongsTo('school')
});
This test is totally green until I add the school attribute. It's even green with 'model:school' defined in the needs array of the moduleForModel helper:
// tests/unit/models/professor-test.js
// this is green w/o belongsTo('school') in the model
moduleForModel('professor', {
// Specify the other units that are required for this test.
needs: ['model:school', 'model:post', 'model:course']
});
The error I'm getting is:
Error: No model was found for 'school'
Here's the models directory
$ ls app/models/
course.js post.js professor.js school.js student.js
Why is it not finding my model?

You need to import the school model in your test:
import '[appName]/models/school';

Related

NextAuth Credentials, adding more to the user scheme

Nextauth with mysql persisting users.
I'm trying out this NextAuth thing to see if this is something I like. So far so good. There is one thing tho which is buggin me and that would be the user scheme. By default it returns a name, image and the last one I forgot.
I'd like to add more to this scheme and found some ways to do it by looking at google, however those I tried did not work.
One example I found is by extending the model which clearly makes sense...
The issue here is then me, I do not know what to change in the code below to make it work with my NextAuth credentials provider. As shown below, this doesnt work.
projectfolder -> models -> index.js
import User, { UserSchema } from "./User"
export default {
User: {
model: User,
schema: UserSchema
}
}
projectfolder -> models -> user.js
import Adapters from "next-auth/adapters"
// Extend the built-in models using class inheritance
export default class User extends Adapters.TypeORM.Models.User.model {
constructor(name, email, image, emailVerified, roles) {
super(name, email, image, emailVerified)
if (roles) { this.roles = roles}
}
}
export const UserSchema = {
name: "User",
target: User,
columns: {
...Adapters.TypeORM.Models.User.schema.columns,
roles: {
type: "varchar",
nullable: true
},
},
}
In my [...nextauth].js file I have my provider, in this provider i've added an profile() field with the extra fields. This did not solve the issue.
profile(profile) {
return {
name: profile.name,
email: profile.email,
role: profile.role
};
},
Please correct me if I am wrong but if I am using credentials, then I need to replace the "TypeORM" with something else, correct? How about the path for the files, are they correct?
This should clearly be quite easy but am I missing something or am I doing something wrong? I feel like there is a lack of documentation on extending the user model for mysql.
I've doubled checked that the role is being retrieved from the database and then added to the user variable shown here:
async authorize ....
const user = {
name: result.display_name,
role: result.role_name,
email: result.email
}
Although I can see the role being set in the variable with my console.log(), I still cannot access the role and that I suspect is because of the model. How would I resolve this? Thanks a lot in advance.
Any ideas?
----------------------- UPDATES ------------------------
Btw, here is my callback
callbacks: {
async signIn({ user, account, profile, email }) {
console.log("user", user);
return true;
},
},
and this is what it returns (shortened)
token: {
token: { name: 'Firstname Lastname', email: 'test#mail.com' },
user: {
name: 'Firstname Lastname',
role: 'administrator',
email: 'test#mail.com'
},
account: { type: 'credentials', provider: 'credentials' },
isNewUser: false,
iat: 1634193197,
exp: 1636785197
}
I'm new to TypeORM and I am facing the same problems as people here.
What I've done was create a separate Entity which I called users_info to store the other information and retrieve it after signing in.
It looks like this:
import { UserEntity } from './NextAuthEntities';
#Entity({ name: 'users_info' })
export class MemberEntity {
#PrimaryGeneratedColumn('increment')
id!: number;
#OneToOne(() => UserEntity)
#JoinColumn({
name: 'auth_id',
referencedColumnName: 'id',
})
auth_id!: UserEntity;
#Column({ type: 'varchar', nullable: true })
full_name!: string | null;
// etc
}
Then, I created a handshake API route to retrieve users_info if the user is signed-in.
When I added a new #Column on my custom UsersEntity, it threw me an error when I tried to login. It seems like TypeORMLegacyAdapter can't be extended or be different from the default UserEntity.
Hope it helps

ember attributes not available in view, only ID

Needless to say, new to Ember and just trying to get a proof of concept done. Already had some help with EmberCLI but this a new oddness for me.
/routes/index.js
export default Ember.Route.extend({
model() {
return this.store.findAll('skill');
}});
/models/skill.js
import Model from 'ember-data/model';
export default Model.extend({
name: DS.attr('string'),
desc: DS.attr('string'),
type: DS.attr('string')
});
/adapters/application.js
import DS from "ember-data";
export default DS.JSONAPIAdapter.extend({
namespace: 'v1',
host: 'http://edu-api.app:8000',
});
/serializers/application.js
import DS from "ember-data";
export default DS.JSONAPISerializer.extend({});
/templates/index.hbs
<h2>Skills</h2>
<ul>
{{#each model as |item|}}
<li>
<div>
<li>{{item}} {{item.id}} {{item.type}} {{item.name}} {{item.desc}}</li>
</div>
</li>
{{/each}}
</ul>
It seems that the id attr is available and correct, but yet all the other attrs are not being loaded from the json. If I copy/paste the json and manually set it in the model, it works as expected, so is there some filtering going on when coming from the model store or serializer?
The JSONAPISerializer and JSONAPIAdapter are not to for simple JSON/REST Backends but for a fully JSONAPI compatible Backend.
You say it works when you copy & paste and set it on the model, so probably you mean something like this:
this.store.createRecord('skill', {
id: '1',
name: 'foo',
desc: 'bar',
type: 'baz'
});
This will indeed work for a model creation but is not a JSONAPI compatible response! In JSONAPI you would have something like this (if the request should return multiple entities:
{
data: [{
id: '1',
attributes: {
name: 'foo',
desc: 'bar',
type: 'baz'
}
}]
}
So now you have two options:
Make your API JSONAPI compatible, or
use a different adapter & serializer.
The RESTSerializer/RESTAdapter are a simple default implementation that can handle a structure like this:
{
id: '1',
name: 'foo',
desc: 'bar',
type: 'baz'
}
Also they are highly customizable.
Checkout the official API for documentation.

Ember data from Mirage fails to display on index.hbs

Ember novice here. I have been following along with the tutorial on the Ember website here.
I have been R&D'ing the example to the word and everything works...until I try implementing Mirage. The data just never shows up on the index.hbs page.
Here's my model hook:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('rental');
},
});
And my model: rental.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
owner: DS.attr('string'),
city: DS.attr('string'),
type: DS.attr('string'),
image: DS.attr('string'),
bedrooms: DS.attr('number')
});
My index.hbs:
<h1> Welcome to Super Rentals </h1>
We hope you find exactly what you're looking for in a place to stay.
{{#each model as |rentalUnit|}}
{{rental-listing rental=rentalUnit}}
{{/each}}
{{#link-to "about"}}About{{/link-to}}
{{#link-to "contact"}}Click here to contact us.{{/link-to}}
and lastly my app/mirage/config.js:
export default function() {
this.get('/rentals', function() {
return {
data: [{
type: 'rentals',
id: 1,
attributes: {
title: 'Grand Old Mansion',
owner: 'Veruca Salt',
city: 'San Francisco',
type: 'Estate',
bedrooms: 15,
image: 'https://upload.wikimedia.org/wikipedia/commons/c/cb/Crane_estate_(5).jpg'
}
}, {
type: 'rentals',
id: 2,
attributes: {
title: 'Urban Living',
owner: 'Mike Teavee',
city: 'Seattle',
type: 'Condo',
bedrooms: 1,
image: 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Alfonso_13_Highrise_Tegucigalpa.jpg'
}
}, {
type: 'rentals',
id: 3,
attributes: {
title: 'Downtown Charm',
owner: 'Violet Beauregarde',
city: 'Portland',
type: 'Apartment',
bedrooms: 3,
image: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Building_-_Portland_Oregon.jpg'
}
}]
};
});
}
I get two messages in Chrome developer console:
Mirage: Your Ember app tried to GET 'http://localhost:4200/assets/vendor.js', but there was no route defined to handle this request. Define a route that matches this path in your mirage/config.js file. Did you forget to add your namespace?
and this warning:
WARNING: Encountered "data" in payload, but no model was found for model name "datum" (resolved model name using super-rentals#serializer:-rest:.modelNameFromPayloadKey("data"))
However it looks like the info was sucessfully retrieved as I see a:
Successful request: GET /rentals
Object {data: Array[3]}
which reflects the proper data. It just is breaking somewhere between that and the index.hbs and I am to novice to figure it out. I'm sure it's just a small misunderstanding on my part. Any help would be appreciated!
You have the wrong version of Ember Data installed. Also make sure you restart the server any time you install a dependency.
The error message that you are getting means that your application is using RESTAdapter (the default adapter for Ember Data 1.x). That is why it looks at the top-level data key and tries to singularize and find the related model.
You can update by following the instructions on the latest Ember CLI release. Or, you can npm install -g ember-cli#beta and start from scratch.

Deleterecord is not deleting object from the HasMany array

I have an event model which has a relationship to a rider model. The event model has a property called riders that is a hasMany of riders and it is also async. The rider model has a property called event that is a belongTo and it contains the proper event that it belongs to. I am loading all of my data from my own REST API that is ran via Node.js and Express 4.
Here is my deletion code:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
deleteRider: function () {
var model = this.get('model');
var evt = model.get('event');
model.deleteRecord();
model.save().then(function() {
evt.save();
});
}
}
});
models/event.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
city: DS.attr('string'),
state: DS.attr('string'),
date: DS.attr('string'),
riders: DS.hasMany('rider', {
async:true,
inverse:'event'
})
});
models/rider.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
city: DS.attr('string'),
state: DS.attr('string'),
BB: DS.attr('boolean'),
SB: DS.attr('boolean'),
BU: DS.attr('boolean'),
event: DS.belongsTo('event')
});
Im having problems to understand what are u exactly trying to delete.
But the way i approach this is. There's an array of Model instances and there's an array of toDeleteModelInstances. The first array is shown on template using each method. And during the delete of each instance you use toDeleteModelInstancesArray.pushObject(selectedInstance)
Looks something like this.
Delete
deleteFieldset: function(givenRecord){
//remove from Each array then push to array containing deleted records
this.get('controller.markedForDeleted.pushObject(givenRecord));
// You now have a record in given array [class,class]
}
Now on EDIT action
var personsToDelete = self.markedForDeleted.map(function(item){
return item.destroyRecord();
});
// Checks for deletedInstances array
if(Ember.isEmpty(personsToDelete)){
deletePersonSuccess();
} else {
Ember.RSVP.all(personsToDelete).then(deletePersonSuccess, deletePersonFailure);
}

Ember.js (Ember Data): Why are sibling relationships disappearing?

I'm having a problem with my sibling hasMany relationships disappearing. Working with Ember data canary.
I have the following data model:
import DS from 'ember-data';
export default DS.Model.extend({
// More here, discarded for brevity...
app: DS.hasMany('app', { async: true }),
paymentMethod: DS.hasMany('paymentMethod', { async: true })
});
When user is updated after deleting a paymentMethod in the following way:
var paymentMethod = this.get('content'),
currentUser = this.session.get('currentUser.content');
currentUser.get('paymentMethod').then(function ( paymentMethods ) {
paymentMethods.removeObject(paymentMethod.get('id'));
paymentMethod.destroyRecord();
currentUser.save();
}, handleError);
or saving in the following way:
var paymentMethod = self.store.createRecord('payment-method', paymentMethodData);
paymentMethod.save().then(function ( PaymentMethod ) {
currentUser.get('paymentMethod').addObject(PaymentMethod);
currentUser.save().then(function ( /* record */ ) {...
The apps array is set to an empty []. It happens the opposite way as well, deleteing or adding an app with a paymentMethod will unset the paymentMethod array.
I have the following serializer in place, but it appears as the relationship is set as an empty array before the record gets to the serializer:
var json = {
_id: user.get('id'),
name: {
first: user.get('firstName'),
last: user.get('lastName'),
company: user.get('companyName')
},
login: {
email: user.get('email'),
password: user.get('password')
},
app: user.get('app').mapProperty('id'),
paymentMethod: user.get('paymentMethod').mapProperty('id'),
time_stamp: user.get('time_stamp')
};
return json;
Sorry for the overload. Hope you can help.
You are naming your hasMany associations in singular, which isn't really following the convention. That being said, you have no 'apps' array. I don't think that should cause you any problems, I am just pointing out because you maybe searching for the wrong thing.
I suppose your backend somehow restricts you to this payload?

Categories