Reputation: 115
I am trying in mongoDB and node to add subscriptions to my competitionEvent object. My issue is that I can write only one subscription and not add them one after another. Here is my http file:
const express = require('express')
import * as bodyParser from 'body-parser'
// import { eventApplication } from './compositionRoot'
import { CompetitionModel } from './mongo'
export const app = express()
app.use(bodyParser.json())
// WORKS - find all events
app.get('/events', async (_req: any, res: any) => {
const comp = await CompetitionModel.find()
res.send(comp)
})
// WOKRS - find just one event
app.get('/events/:event_id', async (req: any, res: any) => {
const searchedComp = await CompetitionModel.find(req.params)
res.send(searchedComp)
})
// WORKS - posts a new comp event
app.post('/new-comp', async (req: any, res: any) => {
const data = await new CompetitionModel(req.body).save()
res.json(data)
})
// WORKS - posts a new subscription into a comp
app.put('/update/:event_id', async (req: any, res: any) => {
const subs = await CompetitionModel.findOneAndUpdate(
{ event_id: req.params.event_id },
{ subscriptions: req.body },
)
res.send(subs)
})
// TO TEST - deletes a competition event
app.delete('/delete/:event_id', async (req: any, res: any) => {
const toDel = await CompetitionModel.deleteOne({
event_id: req.params.event_id,
})
res.json(toDel)
})
and here is my mongo file:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/CompetitionEvent')
export const CompetitionSchema = new mongoose.Schema({
event_id: String,
compName: String,
place: String,
time: String,
subscriptions: [],
date: Date,
cost: {
currency: String,
amount: Number,
},
})
export const CompetitionModel = mongoose.model(
'CompetitionModel',
CompetitionSchema,
)
export const connection = () =>
new Promise((resolve, reject) => {
mongoose.connection.once('open', () => {
resolve()
})
mongoose.connection.once('error', () => {
reject('oooooh shit')
})
})
Every time I tried to change it it would either not modify the competitionEvent, not put anything or simply replace the old subscription with a new one, which makes little sense I am sure you'll agree
Upvotes: 2
Views: 1037
Reputation: 464
First of all fix your schema for subscription mongoose.Schema like below, for better type casting:
Optional
const CompetitionSchema = new mongoose.Schema({
event_id: String,
compName: String,
place: String,
time: String,
subscriptions: [{
//what ever field you wanna add
_id: false //if you don't wanna use it as a sub-document
}],
date: Date,
cost: {
currency: String,
amount: Number,
},
})
Then in your competetionEvent
controller either use mongo $push
operator for adding event subscription at the end of the subscription or use mongo $addToSet
operator for adding the subscription in the subscription field without any duplication.
Remember, $push
doesn't check if the subscription is unique or not, it just pushes elements like javascript Array.push(). On the other hand, $addToSet
checks if the subscription exists or not. If yes then it doesn't add that subscription. If no, then it pushes it to the field Array.
I suggest using $addToSet
as it is more secure & will not create any duplicates of the same subscription.
CODE
app.put('/update/:event_id', async (req: any, res: any) => {
const subs = await CompetitionModel.findOneAndUpdate(
{ event_id: req.params.event_id },
{ $addToSet: {subscriptions: req.body}},
)
res.send(subs)
})
Upvotes: 1
Reputation: 24565
You need to use the $push
-operator to add a new subscription to your competition. Assuming req.body
holds the new subscription, you can do:
app.put('/update/:event_id', async (req: any, res: any) => {
const subs = await CompetitionModel.findOneAndUpdate(
{ event_id: req.params.event_id },
{ $push: { subscriptions: req.body }},
)
res.send(subs)
});
Upvotes: 3