Mongoose population issue at express.js - express

Hello evryone i have issue last 2 days tryin to populate reviews on company list.
Im trying to get list of all companys with their reviews.
Every review is assigned to company Id.
On postman response i get empty array : []
Here is the code im having isuses with;
Company Model:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var slug = require("mongoose-slug-generator");
mongoose.plugin(slug);
var CompanySchema = new Schema({
title: {type: String, required: true},
slug: { type: String, slug: "title" },
address: {type: String, required: true},
totalRating: {type: Number, required: false},
description: {type: String, required: false},
facebookLink: {type: String, required: false},
twitterLink: {type: String, required: false},
googleLink: {type: String, required: false},
linkedIn:{type: String, required: false},
instagramLink:{type: String, required: false},
contactNumber:{type: Number, required: false},
website:{type: String, required: false},
email:{type: String, required: false},
review: [{type: Schema.Types.ObjectId, ref: "Review"}],
user: { type: Schema.ObjectId, ref: "User", required: true },
}, {timestamps: true});
module.exports = mongoose.model("Company", CompanySchema);
Review Model :
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ReviewSchema = new Schema({
title: {type: String, required: true},
description: {type: String, required: true},
rating: {type: String, required: true},
user: { type: Schema.ObjectId, ref: "User", required: true },
company: {type: Schema.ObjectId, ref:"Company"}
}, {timestamps: true});
module.exports = mongoose.model("Review", ReviewSchema);
And where i populate it :
exports.companyList = [
function (req, res) {
try {
Company.
find({id: req._id}).
populate("review").
then((companies)=>{
if(companies.length > 0){
return apiResponse.successResponseWithData(res, "Uspješno 1", companies);
}else{
return apiResponse.successResponseWithData(res, "Uspješno 2", []);
}
});
} catch (err) {
//Baci error 500...
return apiResponse.ErrorResponse(res, err);
}
}
];
Ive tryed evrything thanks infront.

Try changing in your Company Model
review: [{type: Schema.Types.ObjectId, ref: "Review"}]
to
review: {type: Schema.Types.ObjectId, ref: "Review"}
Then when you try to populate, I assume you either pass the _id of the company in your params or body of the request, so most likely:
req.params.id
or
req.body.id
the actual function:
module.exports = {
fncName: (req, res) => {
Company.findById(req.params.id)
.populate({
path: 'review',
})
.exec((err, company) => {
if (!err) {
if(companies.length > 0){
return apiResponse.successResponseWithData(res, "Uspješno 1", companies);
}else{
return apiResponse.successResponseWithData(res, "Uspješno 2", []);
}
}else {
console.log(err)
}
})
}
}
I am not sure how you register the router but it could look something like this:
const router = require ('express-promise-router')();
router.get('/get-company', nameOfTheController.fncName);
Note: to populate review from Company Model you do not necessarily need this line in your Review Model:
company: {type: Schema.ObjectId, ref:"Company"}

Related

How to do Prisma runtime model validation?

In my application, I have validated the input credential at the DTO level by using class-validator. But I need runtime model validation like sequelize ORM.
In sequelize:
'use strict';
import { DataTypes, Sequelize } from 'sequelize';
function User(sequelize: Sequelize) {
const user = sequelize.define(
'User',
{
name: {
type: DataTypes.STRING,
allowNull: false
},
role: {
type: DataTypes.STRING(20),
allowNull: false
},
email: {
type: new DataTypes.STRING,
allowNull: false,
validate: {
isEmail: {
// args: true,
msg: 'Invalid email'
},
len: {
args: [1, 100] as readonly [number, number],
msg: 'Email length should be 1 to 100 characters'
},
notNull: {
// args: true,
msg: 'Email cannot be empty'
}
}
},
password: {
type: DataTypes.VIRTUAL,
allowNull: true,
},
},
{
tableName: 'users',
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
paranoid: true
}
);
return user;
}
export default User;
Is there any possibility to do model validation in Prisma?
There is an open feature request for Prisma to support runtime model validation directly at the Schema level. Alternatively, you can leverage the Client Extensions to perform validation. There is an example in this blog post that shows how to perform custom runtime validation.

Sequelize v5.21 error while initializing model. Dependency name must be given as a not empty string

I have managed to pinpoint the source of the error, despite it not mentioning any file name or anything. The error is Unhandled rejection TypeError: Dependency name must be given as a not empty string
It is occurring when I try to initialize the below model in my Express App
'use strict';
module.exports = (sequelize, DataTypes) => {
const Order = sequelize.define('Order', {
customerName: {
type: DataTypes.STRING,
allowNull: true
},
customerContact: {
type: DataTypes.STRING,
allowNull: true
},
address: {
type: DataTypes.TEXT,
allowNull: true
},
additionalDetails: {
type: DataTypes.TEXT,
allowNull: true
},
areaId: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: sequelize.Area,
key: 'id'
}
},
createdBy: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: sequelize.User,
key: 'id'
}
},
}, {});
Order.associate = function(models) {
// Order.belongsTo(models.Area, {foreignKey: 'areaId', as: 'area'});
};
return Order;
};
However, if I comment/remove the areaId and createdBy attributes the app runs without error and the corresponding tables are created in MySQL Database.
Is there something I am doing wrong, I am using the same syntax in my other models to define foreign keys and they seem to run without error.
Any help would be appreciated, also if someone could point a way to get more descriptive errors while using Sequelize in Express it would be very helpful, as locating the source took me a lot of time due to numerous model definitions.
This problem was resolved after I defined the associations that used areaId and createdBy as foreign keys. Don't know why but without the associations defined, the foreign keys would give an error. Now my model definition is as below
'use strict';
module.exports = (sequelize, DataTypes) => {
const Order = sequelize.define('Order', {
customerName: {
type: DataTypes.STRING,
allowNull: true
},
customerContact: {
type: DataTypes.STRING,
allowNull: true
},
address: {
type: DataTypes.TEXT,
allowNull: true
},
additionalDetails: {
type: DataTypes.TEXT,
allowNull: true
},
areaId: {
type: DataTypes.INTEGER,
references: {
model: sequelize.Area,
key: 'id'
}
},
createdBy: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: sequelize.User,
key: 'id'
}
},
status: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: 'pending'
}
}, {});
Order.associate = function(models) {
Order.belongsTo(models.Area, {foreignKey: 'areaId', as: 'area'});
Order.belongsTo(models.User, {foreignKey: 'createdBy', as: 'user'});
};
return Order;
};

Fulltext mongodb $text search query in graphql-compose-mongoose

I'm unable to figure out how to construct a graphql query for performing the mongodb fulltext search using the text index. https://docs.mongodb.com/manual/text-search/
I've already created a text index on my string in the mongoose schema but I don't see anything in the schemas that show up in the grapqhl playground.
A bit late, though I was able to implement it like so
const FacilitySchema: Schema = new Schema(
{
name: { type: String, required: true, maxlength: 50, text: true },
short_description: { type: String, required: true, maxlength: 150, text: true },
description: { type: String, maxlength: 1000 },
location: { type: LocationSchema, required: true },
},
{
timestamps: true,
}
);
FacilitySchema.index(
{
name: 'text',
short_description: 'text',
'category.name': 'text',
'location.address': 'text',
'location.city': 'text',
'location.state': 'text',
'location.country': 'text',
},
{
name: 'FacilitiesTextIndex',
default_language: 'english',
weights: {
name: 10,
short_description: 5,
// rest fields get weight equals to 1
},
}
);
After creating your ObjectTypeComposer for the model, add this
const paginationResolver = FacilityTC.getResolver('pagination').addFilterArg({
name: 'search',
type: 'String',
query: (query, value, resolveParams) => {
resolveParams.args.sort = {
score: { $meta: 'textScore' },
};
query.$text = { $search: value, $language: 'en' };
resolveParams.projection.score = { $meta: 'textScore' };
},
});
FacilityTC.setResolver('pagination', paginationResolver);
Then you can assign like so
const schemaComposer = new SchemaComposer();
schemaComposer.Query.addFields({
// ...
facilities: Facility.getResolver('pagination')
// ...
});
On your client side, perform the query like so
{
facilities(filter: { search: "akure" }) {
count
items {
name
}
}
}

How to inform a selectfield element from response of Ext.Ajax.request?

I need to inform a selectfield sencha element from callback of Ext.Ajax.request({})
I have a this code, for example,
Ext.Ajax.request({
url: '/express/EXPRESSVE00007_es.jsp',
timeout: 90000,
params: {
evento : action,
cookie: document.cookie,
NAME : Ext.getCmp("txtName").getValue(),
LAST : Ext.getCmp("txtLast").getValue(),
SEX : Ext.getCmp("txtSex").getValue()
},
success: function(r, o) {
var response = r.responseText
response = response.trim()
response = response.replace('\n', '').replace('\r', '')
var jsonResponse = Ext.decode(response)
Ext.Msg.alert(jsonResponse)
},
failure: function() {
Ext.Msg.show({
title: "Failure",
msg: "Error, failed response",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
})
}
})
and my selectfield,
{
xtype: 'selectfield',
id: 'selSex',
name: 'select',
label: '*Sex',
placeHolder: 'Select...',
displayField: 'desc',
hiddenName: 'second-select',
options: [
{desc: '', value: ''},
{desc: '', value: ''}
]
}
In this case, I need to inform "desc" and "value" field from callback Ext.Ajax.request, but I don't know. Please help me.
You can inform the selectfield from an Ext.Ajax.request by updating it's store.
You could declare a store to store all the field values and then on response from the request, you can shuffle the data store to which selectfield is binded.
E.g
{
xtype: 'selectfield',
store: sampleStore,
valueField:'value',
displayField:'desc',
}
and update the store values on Ext.Ajax.request's response like this,
Ext.StoreMgr.get('sampleStore').load();
You can do below
Test = Ext.regModel('Test', {
fields: [{
name: 'desc',
type: 'string'
}, {
name: 'value',
type: 'string'
}]
});
exStores = new Ext.data.Store({
model: 'Test',
autoLoad: false });
and select field
{
xtype: 'selectfield',
store: exStores,
id: 'selSex',
name: 'select',
label: '*Sex',
placeHolder: 'Select...',
valueField:'value',
displayField:'desc',
}
and ajax request
Ext.Ajax.request({
...
success: function(r, o) {
var response = r.responseText
response = response.trim()
response = response.replace('\n', '').replace('\r', '')
var jsonResponse = Ext.decode(response)
exStores.loadData(jsonResponse, false);
Ext.Msg.alert(jsonResponse)
},
...
})
Hope this help.

Deleted records from store keeps showing up

I have created a local store and model for remembering username and password:
Store:
ToolbarDemo.stores.localsettingsstore = new Ext.data.Store({
model: 'UserSettings',
proxy: new Ext.data.LocalStorageProxy(
{
id: 'data',
proxy:
{
idProperty: 'id'
}
}),
autoLoad: true,
autoSave: true,
listeners:
{
beforesync: function()
{
console.log("SYNCING");
console.log("Number of data: ");
console.log(this.getCount());
},
datachanged: function()
{
console.log(this.getProxy());
console.log("DATA CHANGED");
console.log("Number of data: ");
console.log(this.getCount());
}
}
});
Model:
Ext.regModel('UserSettings', {
fields: [
{name: 'username', type: 'string'},
{name: 'password', type: 'string'},
{name: 'storeUsernamePassword', type: 'boolean'}
]
});
If the user want to store the username and password, this function is invoked:
function setLocalUsernameAndPassword(localUsername, localPassword, bStoreUsernameAndPassword)
{
removeLocalUsernameAndPassword(false); // Remove all previous inputs (Should just be one)
ToolbarDemo.stores.localsettingsstore.add({username: localUsername, password: localPassword, storeUsernamePassword: bStoreUsernameAndPassword});
}
The store is set to autoload and autosave, so it should not be nessecary to run a .sync() on the store.
If the user chooses to not store the username and password, i remove all records from the store by invoking:
function removeLocalUsernameAndPassword(bClearFields)
{
//ToolbarDemo.stores.localsettingsstore.removeAll();
ToolbarDemo.stores.localsettingsstore.each(function(record)
{
console.log("Removing " + record.data.username);
ToolbarDemo.stores.localsettingsstore.remove(record);
});
if(bClearFields)
{
Ext.getCmp("usernameField").value = "";
Ext.getCmp("passwordField").value = "";
Ext.getCmp("checkboxStoreUserInfo").checked = false;
}
}
Afterwards i can see that the store is empty, BUT if i refresh the page (Start the app once again), all the records are back plus the one i stored.
Can anyone see what i'm missing to do this properly?
Thanks in advance.
I finally found a guy that had exactly the same problem.
The solution:
You have to add a field with name "id", and type "int".
This makes sencha able to delete the record.
Ext.regModel('UserSettings', {
fields: [
{name: 'id', type: 'int'},
{name: 'username', type: 'string'},
{name: 'password', type: 'string'},
{name: 'storeUsernamePassword', type: 'boolean'}
]
});
After i did this, i also had to do a store.save() after each update.