0

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
  • 1
    "*I get lines in the log but sometimes it points to empty lines in my program*" - this is probably related to the typescript transpilation. Check the line numbers in the output js files. – Bergi Aug 02 '20 at 21:02
  • Where are you calling `subscribe()` and `cancelSubscription()`? – Bergi Aug 02 '20 at 21:04
  • 1
    You're getting the unhandled promise rejection warnings because [you're not handling exceptions](https://stackoverflow.com/q/41349331/1048572) in any of your asynchronous route handlers. Also it should be `const data = await newComp.save();`, don't use a callback and don't `throw error`! – Bergi Aug 02 '20 at 21:07
  • So I've done as you said (meaning removed the Throw error and indeed I don't have the async call issue, but I still can't post. Where exactly should I put the const data = await newComp.save()? I am not sur to understand completely here, sorry ;) – Baptiste Vanlitsenburgh Aug 04 '20 at 11:20
  • 1
    I mean replace the `newComp.save(function (error: any, data: any) {…})` with `const data = await newComp.save(); res.json(data);` – Bergi Aug 04 '20 at 12:39
  • Oooh thanks got it :) – Baptiste Vanlitsenburgh Aug 04 '20 at 14:18

0 Answers0