2

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

2 Answers 2

3

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)
});
Sign up to request clarification or add additional context in comments.

Comments

1

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)
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.