MongoDB help - What am I doing wrong?

const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const mongoose = require('mongoose');

var app = express();

const bodyParser = require('body-parser');
const shortenerRouter = express.Router();

const Schema = mongoose.Schema;
require('mongoose-currency').loadType(mongoose);

const shortUrlSchema = new Schema({
  longUrl: String,
  shortUrl: {type: String}
})

var ShortUrls = mongoose.model('ShortUrls', shortUrlSchema);

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', shortenerRouter);
shortenerRouter.route('/')
.get(function(req, res, next) {
res.json({user: "moi"})
})

app.post('/api/postlongurl', function (req, res, next) {
  const url = 'mongodb://localhost:27017/UrlShortener';
  mongoose.connect(url, {useNewUrlParser: true});

  const db = mongoose.connection;
  db.on('error', console.error.bind(console, 'connection error:'));
  db.once('open', () => {
    console.log("Connected correctly to server");

    var recordUrl = new ShortUrls({longUrl: req.body.longUrl, shortUrl: "test1"})
    recordUrl.save((err, data) => {
        if (err) res.send(err)
        else {
          res.json({ original_url: req.body.longUrl, short_url: data._id.toString() });
        }
      });
  });
})
const PORT = 8080;

app.listen(PORT)
  .on('listening', () => {
    console.clear();
    console.log('server listening on port:', PORT);
  })
  .on('error', (err) => {
    console.error('### error opening port:', PORT);
    console.error(err);
  });

When I try the code above I get:

{
    "driver": true,
    "name": "MongoError",
    "index": 0,
    "code": 11000,
    "keyPattern": {
        "shortUrl": 1
    },
    "keyValue": {
        "shortUrl": "test1"
    }
}

When I change the commands starting in ‘var recordUrl = new shortUrls(…)’ and ‘recordUrl.save(…)’ with:
EDIT: see post below for full code.

ShortUrls.create({longUrl: req.body.longUrl, shortUrl: "test1"}, (err, shortUrl) => {
      if (err) return err;

I get: Could not get response
Error: socket hang up

What am I doing wrong?

Hello!

Can you share your entire code with the change you made, please?

Sure. Sorry.

const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const mongoose = require('mongoose');

var app = express();

const bodyParser = require('body-parser');
const shortenerRouter = express.Router();

const Schema = mongoose.Schema;
require('mongoose-currency').loadType(mongoose);

const shortUrlSchema = new Schema({
  longUrl: String,
  shortUrl: {type: String}
})

var ShortUrls = mongoose.model('ShortUrls', shortUrlSchema);

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));



app.post('/api/postlongurl', function (req, res, next) {
  const url = 'mongodb://localhost:27017/UrlShortener';
  mongoose.connect(url, {useNewUrlParser: true});

  const db = mongoose.connection;
  db.on('error', console.error.bind(console, 'connection error:'));
  db.once('open', () => {
    console.log("Connected correctly to server");


    ShortUrls.create({longUrl: req.body.longUrl, shortUrl: "test1"}, (err, shortUrl) => {
      if (err) return err;
    })
  });
})




const PORT = 8080;

app.listen(PORT)
  .on('listening', () => {
    console.clear();
    console.log('server listening on port:', PORT);
  })
  .on('error', (err) => {
    console.error('### error opening port:', PORT);
    console.error(err);
  });

EDIT: I just looked at someone’s complete solution to the challenge and I did it the opposite (app.get->mongoose) if it matters.

Hmm, the main problem I could find is that you’re not returning a response hence the request times out:

console.log("Connected correctly to server");

ShortUrls.create({longUrl: req.body.longUrl, shortUrl: "test1"}, (err, shortUrl) => {
  if (err) return err; // This is a problem, because there is no response for the request. You're returning, sure, but that's not what the client expects
  // And what happens if there is no error?

})

The req and res parameters of any express defined route correspond to a request and a response respectively.

A request is something a client asks of the server. Even when the client asks for an image, that’s a request.

A response is what the server returns to the client. The typical 404 (not found) error that you see it’s a kind of response too (the server could not find a page).

A client could be the browser or a mobile app (among others); it’s whatever requests information to the server.

In contrast to the code you provided (that works):

// The following handles the requested information
app.post('/api/postlongurl', function (req, res, next) {
  // I omitted some code
    recordUrl.save((err, data) => {
      // If there is an error, respond to the client with that error
      if (err) {
        res.send(err) // In a real world app, don't send the entire error to the client
        // since it may leak sensitive information about the server.
      } else {
          // No error, so we respond with the saved data,
          res.json({ original_url: req.body.longUrl, short_url: data._id.toString() });
     }
     // Both block, the if and the else, conclude the conversation with the client.
  });
});

Can you see the difference? Does this explanation help? If not, let me know :slight_smile:.

1 Like

A little more information from the expressjs site:

First, let me express ( :wink:) my appreciation your help.
Now I added a response, but I get an odd error message which I got with my previous code just as with the new rewrite in this thread.

TypeError: conn.openUri(...).then is not a function
    at Mongoose.connect

Any idea how should I try to debug it?

That’s because the openUri doesn’t return a promise, you must provide a callback to it.

However, I don’t know why you would need it if you’re connecting to the database in a different way:

const url = 'mongodb://localhost:27017/UrlShortener';
  mongoose.connect(url, {useNewUrlParser: true});

  const db = mongoose.connection;
  db.on('error', console.error.bind(console, 'connection error:'));
  db.once('open', () => {
    console.log("Connected correctly to server");
   // ...
  });