javascript - HTTP put-förfrågan i node och mongodb


Jag försöker i MongoDB och Node att lägga till prenumerationer till mitt competitionEvent-objekt. Mitt problem är att jag bara kan skriva en prenumeration och inte lägga till dem en efter en. Här är min http-fil:

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

och här är min mongo-fil:

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

Varje gång jag försökte ändra det skulle det antingen inte ändra competitionEvent, inte lägga till något eller helt enkelt ersätta den gamla prenumerationen med en ny, vilket knappt är logiskt, jag är säker på att du håller med

Svar #1

Du behöver använda $push-operatorn för att lägga till en ny prenumeration till din tävling. Förutsatt att req.body innehåller den nya prenumerationen kan du göra:

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

Svar #2

Först och främst, fixa ditt schema för prenumeration mongoose.Schema som nedan, för bättre typomvandling:

Valfritt

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

Sedan i din competetionEvent-kontroller, använd antingen mongo $push-operatorn för att lägga till händelseprenumerationen i slutet av prenumerationen eller använd mongo $addToSet-operatorn för att lägga till prenumerationen i prenumerationsfältet utan någon duplicering.

Kom ihåg, $push kontrollerar inte om prenumerationen är unik eller inte, det trycker bara in element precis som javascript Array.push(). Å andra sidan kontrollerar $addToSet om prenumerationen finns eller inte. Om ja, lägger den inte till den prenumerationen. Om nej, så lägger den till den i fältets Array.

Jag föreslår att använda $addToSet eftersom det är säkrare och inte kommer att skapa några duplicerade abonnemang.

KOD

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