hi guys I have some problems, why this.day_number and this.teacher_id is undefined?
'use strict'
module.exports = (sequelize, DataTypes) => {
const Teacher = sequelize.models.teachers
const TimeSlot = sequelize.define('time_slots', {
day: {
type: DataTypes.STRING,
validate: {
notEmpty: {
msg: 'Hari harus diisi.'
},
isIn: {
args: [['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu']],
msg: "Hari tidak tersedia."
}
}
},
day_number: {
type: DataTypes.TINYINT,
validate: {
notEmpty: {
msg: 'Urutan hari harus diisi.'
},
isInt: {
msg: 'Urutan hari harus berupa angka.'
},
isIn: {
args: [[0, 1, 2, 3, 4, 5, 6]],
msg: "Urutan hari tidak tersedia."
}
}
},
time: {
type: DataTypes.TIME,
validate: {
notEmpty: {
msg: 'Waktu mulai harus diisi.'
},
isExists: (value, next) => {
TimeSlot.findOne({
where: {
time: value,
day_number: this.day_number,
teacher_id: this.teacher_id
},
attributes: ['id']
})
.then((data) => {
if (data) {
return next('Waktu mengajar sudah digunakan.')
}
next()
})
.catch((err) => {
next(err)
})
}
}
},
teacher_id: {
type: DataTypes.STRING,
validate: {
notEmpty: {
msg: 'Guru belum dipilih.'
},
isExists: (value, next) => {
Teacher.findOne({
where: {
id: value
},
attributes: ['id']
})
.then((data) => {
if (!data) {
return next('Guru tidak tersedia.')
}
next()
})
.catch((err) => {
next(err)
})
}
}
}
}, {
timestamps: true,
freezeTableName: true,
updatedAt: 'updated_at',
createdAt: 'created_at'
})
TimeSlot.associate = (models) => {
TimeSlot.belongsTo(models.teachers, {
foreignKey: 'teacher_id',
onDelete: 'CASCADE',
as: 'teacher'
})
}
return TimeSlot
}
You're using arrow functions and arrow functions don't bind this.(MDN - Arrow functions)
Replace all arrow functions like the code below.
isExists(value, next) {
TimeSlot.findOne({
where: {
time: value,
day_number: this.day_number,
teacher_id: this.teacher_id
},
attributes: ['id']
})
.then((data) => {
if (data) {
return next('Waktu mengajar sudah digunakan.')
}
next()
})
.catch((err) => {
next(err)
})
}
Related
I have build two schemas, one for posts and one for comments.
const PostSchema = new Schema(
{
title: { type: String, required: true },
text: { type: String, required: true },
author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
status: { type: Boolean, default: true },
},
{ timestamps: true }
);
, and:
const CommentSchema = new Schema(
{
text: { type: String, required: true, minlength: 5 },
author: { type: String, required: true },
post: { type: Schema.Types.ObjectId, ref: 'Post' },
},
{
timestamps: true,
}
);
Now I want to make a GET request which finds all posts and would populate each post with its comments. So far I have this, but I am hitting a wall. If I try to do it like this, I can't add .toArray(), and it doesn't even add new field to the allPosts.
exports.allPosts_GET = (req, res) => {
Post.find()
.populate('author')
.sort('-createdAt')
.exec((err, allPosts) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
} else if (allPosts.length === 0) {
return res.status(404).json({
success: false,
msg: 'No posts find in the database!',
});
}
allPosts.map((post) => {
post.comments = Comment.find({post: post._id}).
//to array somehow and populate all posts
});
console.log(allPostsStore);
res.status(200).json({ success: true, posts: allPosts });
});
};
So I came up with a solution, I updated my Post schema that contains an array with reference to ids of comments. Like that:
const PostSchema = new Schema(
{
title: { type: String, required: true },
text: { type: String, required: true },
author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
status: { type: Boolean, default: true },
},
{ timestamps: true }
);
And then when you make a new comment, you reference it to a post, and also save it to array of comments, like that:
exports.createNewComment_POST = (req, res) => {
const { text, author, postID } = req.body;
const newComment = new Comment({
text,
author,
post: postID,
});
newComment
.save()
.then((comment) => {
Post.findByIdAndUpdate(
postID,
{ $push: { comments: comment._id } },
{ new: true, useFindAndModify: false },
(err, post) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
}
res.status(200).json({ success: true, comment });
}
);
})
.catch((err) => {
res.status(500).json({ success: false, msg: err.message });
});
};
Getting all posts with their comments, you just use find() and populate(), like that:
exports.allPosts_GET = (req, res) => {
Post.find()
.populate('author', '-password')
.populate('comments')
.sort('-createdAt')
.exec((err, posts) => {
if (err) {
return res.status(500).json({ success: false, msg: err.message });
} else if (posts.length === 0) {
return res.status(404).json({
success: false,
msg: 'No posts find in the database!',
});
}
res.status(200).json({ success: true, posts: posts });
});
};
Envelope: Cannot read property 'id' of undefined in sails.js
Whenever i have have send create request they give me above error,
model : Car.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true,
unique: true
},
engine: {
type: 'String',
},
type: {
type: 'String'
},
colors: {
collection: 'color',
via: 'car'
}
},
};
model : Color.js
module.exports = {
attributes: {
color: {
type: 'String',
unique: true,
required: true
},
car: {
model: 'car',
required: true
}
},
};
CarController.js
please help me as fast as possible
bcz i have amateur learner in sails.js
create: async function (req, res) {
let name = req.param('name');
let engine = req.param('engine');
let type = req.param('type');
let colorName = req.param('color');
if(!name){
res.badRequest({err : 'invalid Name'});
}
if(!engine){
res.badRequest({err : 'invalid Engine'});
}
if(!type){
res.badRequest({err : 'invalid Type'});
}
if(!colorName){
res.badRequest({err : 'invalid Color Name'});
}
await Car.create({
name: name,
engine: engine,
type: type
})
.exec((err, newcar) => {
if(err) {
return res.serverError(err);
}
//Create New Color
Color.create({
color: colorName,
car: newcar.id,
})
.exec((err, _color) => {
if(err) {
return res.serverError(err);
}
})
res.send(newcar, _color);
})
},
It's look like id error, please solve as fast as possible
Lookups working in sails.js
find: async(req, res) => {
try{
let doc = await db.collection('color').aggregate([
{
$lookup: {
from: 'car',
localField: 'carID',
foreignField: 'carID',
as: 'Car'
}
}
]).toArray();
res.ok(doc);
} catch (error) {
return res.badRequest(error);
}
}
I'm creating a Reddit clone and I'm setting up the backend first, but having trouble creating relational data.
When I use this query:
query {
subreddit(id: 1) {
name
posts {
title
}
}
}
I expect:
{
"data": {
"subreddit": {
"name": "javascript"
"posts": [
{
"title": "JS Post"
}
]
}
}
}
What I get:
{
"data": null,
"errors": [
{
"message": "Cannot return null for non-nullable field Subreddit.posts.",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"subreddit",
"posts"
]
}
]
}
Here's the schema:
type Query {
subreddits: [Subreddit!]!
subreddit(id: ID!): Subreddit!
posts: [Post!]!
post(id: ID!): Post!
}
type Mutation {
createSubreddit(
name: String!
description: String!
contentType: String!
ageRestriction: Boolean!
): Subreddit!
}
type Subreddit {
id: ID!
name: String!
description: String!
contentType: String!
ageRestriction: Boolean!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
body: String!
subredditId: ID!
# userId: ID!
}
Here is server/index.js:
const { GraphQLServer } = require('graphql-yoga');
let dummySubreddits = [
{
name: 'javascript',
description: 'all things javascript',
contentType: 'any',
ageRestriction: false,
id: 1
},
{
name: 'react',
description: 'all things react',
contentType: 'any',
ageRestriction: false,
id: 2
},
{
name: 'primsa',
description: 'all things prisma',
contentType: 'any',
ageRestriction: false,
id: 3
}
];
let idCountSubreddit = dummySubreddits.length;
let dummyPosts = [
{ title: 'JS Post', body: 'Body of post one', id: 1, subredditId: 1 },
{ title: 'React Post', body: 'Body of post two', id: 2, subredditId: 2 },
{
title: 'Prisma Post',
body: 'Body of post three',
id: 3,
subredditId: 3
}
];
let idCountPost = dummyPosts.length;
const resolvers = {
Query: {
subreddits: () => dummySubreddits,
subreddit: (parent, args) => {
return dummySubreddits.find(obj => obj.id == args.id);
},
posts: () => (parent, args) => {
return dummyPosts.find(obj => obj.subredditId == parent.id);
},
post: (parent, args) => {
return dummyPosts.find(obj => obj.id == args.id);
}
},
Mutation: {
createSubreddit: (parent, args) => {
let subreddit = {
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
};
return subreddit;
}
}
};
const server = new GraphQLServer({ typeDefs: './schema.graphql', resolvers });
server.start(() => console.log('Server is running on localhost:4000'));
I'm using the GraphQL desktop app for querying and I do not have grapql-yoga config file.
Where am I going wrong? I'd like to be pointed in the right direction so I can figure it out myself. This is my first time working with GraphQL alone, after doing some tutorials on YouTube, however they used graphql-express and I'm using graphql-yoga.
Move the resolver you have written for Query's posts into Subreddit to resolve the posts field there. If your resolver does not comply to the default resolver implementation:
(parent) => parent[fieldName]
Like in your case
(parent) => parent.posts
You have to specify it yourself. If your field posts on Query should display all the posts you might want to go for the following implementations:
const resolvers = {
Query: {
subreddits: () => dummySubreddits,
subreddit: (parent, args) => {
return dummySubreddits.find(obj => obj.id == args.id);
},
posts: () => dummyPosts,
post: (parent, args) => {
return dummyPosts.find(obj => obj.id == args.id);
}
},
Subreddit: {
posts: () => (parent, args) =>
dummyPosts.filter(obj => obj.subredditId == parent.id),
},
Mutation: {
createSubreddit: (parent, args) => {
let subreddit = {
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
};
return subreddit;
}
}
};
I had to add a resolver for subreddit to deal with posts.
const resolvers = {
Query: {
subreddits: () => dummySubreddits,
subreddit: (parent, args) => {
return dummySubreddits.find(obj => obj.id == args.id);
},
posts: (parent, args) => {
return dummyPosts;
},
post: (parent, args) => {
return dummyPosts.find(obj => obj.id == args.id);
}
},
Mutation: {
createSubreddit: (parent, args) => {
let subreddit = {
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
};
return subreddit;
}
},
// This resolver was needed
Subreddit: {
posts: subreddit =>
dummyPosts.filter(obj => obj.subredditId == subreddit.id)
}
};
mongoose categorySchema:
const CategoryAdvertSchema = new mongoose.Schema({
UniqueHomes: {
cave: { type: Boolean, default: false },
natureLodge: { type: Boolean, default: false },
castle: { type: Boolean, default: false },
farmStay: { type: Boolean, default: false }
},
PropertyType: {
apartment: { type: Boolean, default: false },
villa: { type: Boolean, default: false },
loft: { type: Boolean, default: false },
yurt: { type: Boolean, default: false }
},
Others: [CategoryDynamiqueSchema]
});
My mongoose OthersShema for push array:
const CategoryDynamiqueSchema = new mongoose.Schema({
dayOfCategory: { type: Date, default: Date.now },
nameOfCategory: { type: String },
typeOfCategory: { type: String }
});
My API:
category.post('/category', jwt.checkUserToken, (req, res) => {
const dayOfCategory = Date.now();
const nameOfCategory = req.body.nameOfCategory;
const typeOfCategory = req.body.typeOfCategory;
CategoryAdvert.update({
$push: {
Others: {
dayOfCategory: dayOfCategory,
nameOfCategory: nameOfCategory,
typeOfCategory: typeOfCategory
}
}
}, { new: true }, (err, category) => {
if (err) {
res.json({ success: false });
console.log('err : ', err);
} else {
console.log("La catégorie '" + nameOfCategory + "' a bien été ajouté");
res.json({ success: true });
}
});
});
When I try to push an array I get the following error:
TypeError: CategoryAdvert.update is not a function
i have make light change and it's working
category.post('/category', jwt.checkUserToken, (req, res) => {
console.log('req.body => ', req.body);
const dayOfCategory = Date.now();
const nameOfCategory = req.body.nameOfCategory;
const typeOfCategory = req.body.typeOfCategory;
Advert.update({
$push: {
'CategoryAdvert.Others': {
dayOfCategory: dayOfCategory,
nameOfCategory: nameOfCategory,
typeOfCategory: typeOfCategory
}
}
}, { new: true }, (err, category) => {
if (err) {
res.json({ success: false });
console.log('err : ', err);
} else {
console.log("La catégorie '" + nameOfCategory + "' a bien été ajouté");
res.json({ success: true });
}
});
});
I am having an issue when I'm trying to associate a table into my query with sequelize-cli.
My query works but it doesn't populate Adresse table. Only Patient is populated. Adresse array is ignored. (return null)
I made a one-to-one relationship between the tables and am not sure if that's the cause of the error or if it is somewhere else where I am associating the two tables.
here is my models :
server/models/patient.js
module.exports = (sequelize, Sequelize) => {
const Patient = sequelize.define('Patient', {
///
}, {
classMethods: {
associate: (models) => {
Patient.belongsTo(models.Adresse, {
foreignKey: 'adresseId',
});
}
}
});
return Patient;
};
server/models/adresse.js
module.exports = function(sequelize, Sequelize) {
const Adresse = sequelize.define('Adresse', {
adresse: {
type: Sequelize.STRING,
allowNull: false,
},
complementAdr: {
type: Sequelize.STRING
},
codePostal: {
type: Sequelize.INTEGER,
allowNull: false
},
}, {
classMethods: {
associate: (models) => {
Adresse.hasMany(models.Patient, {
foreignKey: 'adresseId',
as: 'Patients',
});
}
}
});
return Adresse;
};
and here is where I specified the association on my migration files :
server/migrations/20170326145609-create-patient.js
adresseId: {
type: Sequelize.INTEGER,
references: {
model: 'Adresses',
key: 'id_adresse',
as: 'adresseId',
},
},
server/migrations/20170326145502-create-adresse.js
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Adresses', {
id_adresse: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
adresse: {
type: Sequelize.STRING,
allowNull: false,
},
complementAdr: {
type: Sequelize.STRING
},
codePostal: {
type: Sequelize.INTEGER,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Adresses');
}
};
and finally here is my query on my controller file :
server/controllers/patients.js
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const Patient = require('../models').Patient;
const Adresse = require('../models').Adresse;
module.exports = {
create(req, res) {
return Patient
.create({
///
adressesId: {
adresse: req.body.adresse,
codePostal: req.body.codePostal,
}
}, {
include: [{
model : Adresse
}]
})
.then(patient => res.status(201).send(patient))
.catch(error => res.status(400).send(error));
}
};
Try using Adresse instead adresseId when eager creating the Adresse model instance related to given Patient
return Patient.create({
// patient attributes,
Adresse: {
adresse: req.body.adresse,
codePostal: req.body.codePostal
},
include: [ Adresse ]
}).then(patient => {
// look at the query generated by this function
// it should create both patient and adresse
});