Facing some errors in CRUD operation? - javascript

I created a program for CRUD but facing issues
Controller program :-
const Greeting = require("../models/model.js");
exports.create = (req, res) => {
if (!req.body.message) {
return res.status(400).send({ message: "Note content can not be empty" });
}
const greeting = new Greeting({
name: req.body.name || "Name Needed",
message: req.body.message,
});
Greeting.pushData(greeting);
};
modules.js
const GreetingSchema = mongoose.Schema(
{
name: String,
message: String,
},
{
timestamps: true,
}
);
module.exports = mongoose.model("Greeting", GreetingSchema);
const Schema = mongoose.model("Greeting", GreetingSchema);
pushData = (greeting) => {
const data = new Schema({
name: greeting.name,
message: greeting.message
});
data
.save()
.then((data) => {
res.send(data);
})
.catch((err) => {
res
.status(500)
.send({
message: err.message || "Error Occurred while creating Greeting",
});
});
}
module.exports = {pushData};
and getting errors:
*
TypeError: Greeting is not a constructor
at exports.create (E:\Projects\Greeting-App_backend - Copy\controller\controller.js:9:20)
at Layer.handle [as handle_request] (E:\Projects\Greeting-App_backend - Copy\node_modules\express\lib\router\layer.js:95:5)
at next (E:\Projects\Greeting-App_backend - Copy\node_modules\express\lib\router\route.js:137:13)*

There are few errors in your code.
pushData method should be part of Schema if you want to keep it inside models and access through model Schema. No need to export pushData if you do it like below.
GreetingSchema.methods.pushData = (greeting) => {
// your code
}
module.exports = mongoose.model("Greeting", GreetingSchema);
In controller it will be -
greeting.pushData(greeting);

The error shows that your Greeting model is not a constructor. Check your model again to see if it's in the right format of how to create constructor in Javascript.
function Greeting(greeting) {
this.name = greeting.name;
this.message = greeting.message;
}

Related

TypeError deleting a file with gridfs mongoose and node.js

I am developing an application that allows uploading and downloading music.
I can upload files, send them to the client... however, I have problems when it comes to deleting a bucket file...
I'am using "mongoose": "^6.2.1".
My controller, where podcastId is a ObjectId:
const connection = require('../database')
const mongoose = require('mongoose')
const Users = require('../models/Users')
const PodcastInfo = require('../models/PodcastInfo')
ctrPod.deletePodcast = async (req, res, next) => {
try {
const id = req.params.idPodInfo
const info = await PodcastInfo.findById(id)
const { userId, podcastId } = info
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection, {
bucketName: 'podcasts',
});
gridFsBucket.delete(podcastId, (err) => {
console.log(err)
})
.
.
.
I get this error:
TypeError: Cannot use 'in' operator to search for 'client' in undefined
at getTopology
The problem appears here, \node_modules\mongodb\lib\utils.js:363:23) :
function getTopology(provider) {
if (`topology` in provider && provider.topology) {
return provider.topology;
}
else if ('client' in provider.s && provider.s.client.topology) {
return provider.s.client.topology;
}
else if ('db' in provider.s && provider.s.db.s.client.topology) {
return provider.s.db.s.client.topology;
}
throw new error_1.MongoNotConnectedError('MongoClient must be connected to perform this operation');
}
////////////////////////
delete(id, callback) {
return (0, utils_1.executeLegacyOperation)((0, utils_1.getTopology)(this.s.db), _delete, [this, id, callback], {
skipSessions: true
});
}
/////////////////////////////////////
What am I doing wrong?
I think the problem lies here:
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection, {
bucketName: 'podcasts',
});
new mongoose.mongo.GridFSBucket(db,{bucketName}) takes in a db not a connection. Try:
const gridFsBucket = new mongoose.mongo.GridFSBucket(connection.db, {
bucketName: 'podcasts',
});

nodejs TypeError: Cannot read property 'Message' of undefined

I have a lambda function in AWS. I use it to retrieve information from a REST API. When I test it runs returns a 200 status code, but an "ERROR TypeError: Cannot read property 'Message' of undefined
at smsResponder (/var/task/smsResponder.js:33:35)" also shows. I have googled, and tried to use .responseText.
My code is below. Should I be using return or something of the sort?
'use strict'
const AWS = require('aws-sdk')
AWS.config.update({ region: process.env.AWS_REGION || 'us-east-1' })
const { getStock } = require('./getStock')
const KEYWORD = 'stock'
const validateStock = function (elementValue){
let stockTest = AAPL
return stockTest.test(elementValue)
}
const sendSMS = async function (params) {
const pinpoint = new AWS.Pinpoint()
console.log('sendSMS called: ', params)
return new Promise((resolve, reject) => {
pinpoint.sendMessages(params, function(err, data) {
if(err) {
console.error(err)
reject(err)
} else {
console.log("Message sent. Data: ", data)
resolve(data)
}
})
})
}
const smsResponder = async (event) => {
const msg = JSON.parse(event.Sns.Message)
const msgWords = msg.messageBody.split(" ")
// Check the first word of the text message is the keyword
if (msgWords[0].toLowerCase() !== KEYWORD) return console.log('No keyword found - exiting')
// Validate stock name and get price
let message =''
const stockCode = msgWords[1]
if (validateStock(stockCode)) {
message = await getStock(stockCode)
} else {
message = 'Invalid stock symbol - text me in the format "stock stocksymbol".'
}
// Send the SMS response
const params = {
ApplicationId: process.env.ApplicationId,
MessageRequest: {
Addresses: {
[msg.originationNumber]: {
ChannelType: 'SMS'
}
},
MessageConfiguration: {
SMSMessage: {
Body: message,
MessageType: 'PROMOTIONAL',
OriginationNumber: msg.destinationNumber
}
}
}
}
return console.log(await sendSMS(params))
}
module.exports = { smsResponder }
The SNS-Event is differently structured, it should be event.Records[0].Sns.Message .
Here are the docs:
https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html

Unhandled promise rejection - Typescript wit hexpress and mongoose

Please bear with me, I am a beginner in node and async stuff is still no super clear for me.
I have the below piece of code and I a now working on the last part - the /new-comp route.
It is supposed to post in the database I connected above:
import { Schema } from 'mongoose'
export const mongoose = require('mongoose')
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const urlEncodedParser = bodyParser.urlencoded({ extended: false })
mongoose.connect('mongodb://localhost:27017/CompetitionEvent')
export const db = mongoose.connection
db.on('error', console.error.bind(console, 'An error has occured: '))
db.once('open', function () {
console.log('Connected to Mongodb')
})
const CompetitionSchema = new Schema({
id: String,
place: String,
time: String,
subscriptions: [],
date: Date,
cost: {
currency: String,
amount: Number,
},
})
const CompetitionModel = mongoose.model('CompetitionModel', CompetitionSchema)
app.use(bodyParser.json())
app.get('/events', (_req: any, res: any) => {
res.send(eventApplication.getAll())
})
app.post('/event', async (req: any, res: any) => {
await eventApplication.createAnEvent(req.body)
res.json({
success: true,
})
})
app.post('/new-comp', urlEncodedParser, async (res: any, req: any) => {
await eventApplication.createAnEvent(req.body)
const newComp = CompetitionModel(req.body)
newComp.save(function (error: any, data: any) {
if (error) throw error
res.json(data)
})
})
app.listen(8000)
I also have this file that has all my classes:
export interface Subscription {
id: string
event_id: string
name: string
surname: string
}
export interface EventDTO {
id: string
place: string
time: string
subscriptions: Subscription[]
date: Date
cost: EventCost
}
export interface EventCost {
amount: number
currency: string
}
export class CompetitionEvent {
public subscriptions: Subscription[]
public place: string
public time: string
public date: Date
public cost: EventCost
public id: string
static save: any
constructor(data: EventDTO) {
this.subscriptions = data.subscriptions
this.place = data.place
this.time = data.time
this.date = data.date
this.cost = data.cost
this.id = data.id
}
public isCompleted = () => this.place === 'Poznan' && this.date === new Date()
public getSubs = () => this.subscriptions
public subscribe = (sub: Subscription) => {
this.subscriptions = [...this.subscriptions, sub]
return this
}
public cancelSubscription(subscription: Subscription) {
const subExists = this.subscriptions.find(
(it) => it.id === subscription.id && it.name === subscription.name,
)
if (!subExists) {
throw new Error('Subscription does not exist.')
}
this.subscriptions = this.subscriptions.filter(
(it) => it.id !== subscription.id,
)
}
}
Now my issue is that when I post some data to my app using curl, I have anerror message from the server as follows:
(node:3264) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'subscriptions' of undefined
I am not sure how to understand this log. It seems that I have an unhandled promise somewhere (I get lines in the log but sometimes it points to empty lines in my program".
Do you have any idea how I should understand / manage this issue?
Thanks in advance

Mocking mongoose save() error inside a route

After trying all manner of methods to test a route's mongoose save() throwing, I was not really sure how it should be done. I'm aiming for 100 % coverage with istanbul. Here's the core setup:
model.js
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let PasteSchema = new Schema(
{
message: { type: String, required: true },
tags: [String],
marked: { type: Boolean, default: false },
createdAt: { type: Date, default: Date.now },
updatedAt: Date
}
);
module.exports = mongoose.model('paste', PasteSchema);
controller.js
let Paste = require('./model');
// Other stuff
// I use a bit non-standard DELETE /pastes/:id for this
const markPaste = (req, res) => {
Paste.findById({ _id: req.params.id }, (err, paste) => {
if (!paste) {
res.status(404).json({ result: 'Paste not found' });
return;
}
paste.marked = true;
paste.updatedAt = new Date();
paste.save((err) => {
err
? res.status(400).json({ result: err })
: res.json({ result: 'Paste marked' });
});
});
}
module.exports = {
markPaste,
// Other stuff
}
routes.js
const express = require('express');
const app = express();
const pastes = require('./apps/pastes/controller'); // The file above
app.route('/pastes/:id')
.delete(pastes.markPaste);
module.exports = app;
In the below test, I want to simulate an error being thrown in the paste.save((err) => { above.
process.env.NODE_ENV = 'test';
let mongoose = require('mongoose');
let Paste = require('../apps/pastes/model');
let server = require('../index');
let chai = require('chai');
chai.use(require('chai-http'));
chai.use(require('chai-date-string'));
let expect = chai.expect;
let sinon = require('sinon');
let sandbox = sinon.createSandbox();
let pastes = require('../apps/pastes/controller');
let httpMocks = require('node-mocks-http');
// Other tests
Then the test I want to test save() error in the route:
it('should handle an error during the save in the endpoint', (done) => {
// Create a paste to be deleted
const pasteItem = new Paste({ message: 'Test 1', tags: ['integration', 'test'] });
pasteItem.save()
.then((paste) => {
// Attempt code from below goes here
})
.catch((err) => {
console.log('Should not go here');
});
done();
});
I didn't really find any clear reference to this in various Stack questions, or online, so here's how I did it:
The secret is in using the sinon sandbox, which applies even inside the route context during tests. Here is the working test:
it('should handle an error during the save in the endpoint', (done) => {
const pasteItem = new Paste({ message: 'Test 1', tags: ['integration', 'test'] });
pasteItem.save()
.then((paste) => {
// the sandbox is defined in the imports
// This forces calling save() to raise an error
sandbox.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
chai.request(server)
.delete('/pastes/' + paste._id)
.end((err, res) => {
// It applies within the route handling, so we get the expected 400
expect(res).to.have.status(400);
done();
});
})
.catch((err) => {
console.log('Should not go here');
});
});
If you would call it outside of the sandbox, you would break all subsequent tests that use sinon. Ie.
// This would break things unintendedly
sinon.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
// This only breaks things (on purpose) in the test we want it to break in:
sandbox.stub(mongoose.Model.prototype, 'save').yields({ error: 'MongoError' });
If you have multiple things within the particular sandbox instance, you can of course restore the "unbroken" state within the test with sandbox.restore(); after the test case.
->
=============================== Coverage summary ===============================
Statements : 100% ( 60/60 )
Branches : 100% ( 14/14 )
Functions : 100% ( 0/0 )
Lines : 100% ( 57/57 )
================================================================================
Yay!

Cannot read property 'kind' of undefined at isDocumentNode while export makeExecutableSchema using Apollo Graphql on express js

I have created modular of schema like this: User.js
const gqTools = require('graphql-tools');
const user = `
type User {
emailId: String
name: String
type: Int
created_on: String
}
`;
module.exports = user
and this is the UserPayload that has related by the user type schema
const gqTools = require('graphql-tools');
const User = require('./User')
const userPayload = `
enum ErrorCodes {
UNAUTHORIZED
INTERNAL_ERROR
}
type Error {
code: ErrorCodes
msg: String
}
type UserPayload {
user: [User]
error: Error
}
`;
module.exports = () => [userPayload, User]
this is the Type Query of user that i created
const gqTools = require('graphql-tools');
const UserPayload = require('../UserPayload')
const query = `
type Query {
checkAuthorized: [UserPayload]
}
`;
module.exports = () => [query, UserPayload]
this is the resolver i created
const checkAuthorizedResolver = {
async checkAuthorized(root, data, context) {
if (context.user.length === 0) {
return {
user: null,
error: {
code: 'UNAUTHORIZED',
msg: 'UNAUTHORIZED'
}
}
}
let s = `
select email, name, usertype_id, created_at
from users
where id = ${context.user[0].id}
`
try {
let result = await context.db.run(s)
return {
user: {
emailId: result[0].email,
name: result[0].name,
type: result[0].usertype_id,
created_on: result[0].created_at
},
error: null
}
} catch (err) {
console.log(err)
return {
user: null,
error: {
code: 'UNAUTHORIZED',
msg: 'UNAUTHORIZED'
}
}
}
}
}
module.exports = checkAuthorizedResolver
after it i create the main.js on schema folder that will be import on server.js
const gqTools = require('graphql-tools');
const jwt = require('jsonwebtoken')
const { makeExecutableSchema } = require('graphql-tools')
const moment = require('moment')
const {
checkAuthorized,
} = require('../schema/type_Query/type_Query')
const checkAuthorizedResolver = require ('../Controller/checkAuthorized')
module.exports = makeExecutableSchema({
typeDefs: [checkAuthorized],
resolvers:{
checkAuthorizedResolver
}
})
after i run the program it show the error msg, i dont understand what is mean of "kind" on the error msg because i never declare variable "kind", and i know it is from node module library. may everyone help me what is mean of that error and how to write the syntax on "makeExecutableSchema", because i have follow the documentation from GrahQL Tools for modularization
this is the error msg:
> TypeError: Cannot read property 'kind' of undefined
> at isDocumentNode (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools/src/schemaGener
> ator.ts:134:42)
> at /home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools/src/schemaGenerator.ts:151:9
> at Array.forEach (<anonymous>)
> at concatenateTypeDefs (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools/src/schema
> Generator.ts:150:22)
> at buildSchemaFromTypeDefinitions (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools
> /src/schemaGenerator.ts:190:21)
> at _generateSchema (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools/src/schemaGene
> rator.ts:80:18)
> at makeExecutableSchema (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/graphql-tools/src/schem
> aGenerator.ts:109:20)
> at Object.<anonymous> (/home/hari/Documents/kerjaan/nest8gg/kpi/server/schema/main.js:41:18)
> at Module._compile (module.js:643:30)
> at Module._compile (/home/hari/Documents/kerjaan/nest8gg/kpi/node_modules/source-map-support/source-ma
> p-support.js:492:25)
Most likely you pass a undefined as type, for example, User or UserPayload:
module.exports = () => [userPayload, User]
module.exports = () => [query, UserPayload]
You can log them out and make sure they have valid values:
console.log(User);
module.exports = () => [userPayload, User]
console.log(UserPayload);
module.exports = () => [query, UserPayload]

Categories