Dilbert
Dilbert

Reputation: 23

How to fix Uncaught TypeError: Cannot read property 'id' of null in node?

I am trying to create a web page application using node, ember and mongodb which is able to edit or to delete the existing songs on my database, the webpage is already able to display the songs and to add new ones. The problem occurs when I click on my "EDIT" link next to a song - it throws "Uncaught TypeError: Cannot read property 'id' of null" when it's supposed to fetch me a song by it's id.

Here's my app/routes.js code:

...
router.route('/songs/:song_id')
 .put(function(req, res) { songs.updateSong(req, res, req.params.song_id) })
 .delete(function(req, res) { songs.deleteSong(req, res, req.params.song_id) });
...

Here's my api/song.js code:

...
module.exports.findById = function(req, res) {
  console.log(req.params.id);
  Song.findById(req.params.id ,function(err, data){
    if(err){console.log(err);}
    console.log(data);
    return res.send({
      song: data
    });
  });
};
...

Here's my app/router.js code:

...
var SongSchema = new mongoose.Schema({
  title: String,
  artist: String,
  year: Number,
  genre: String,
  lyrics: String
});
...
app.get('/api/songs/:id', function(req, res){
  console.log(req.params.id);
  Song.findById(req,res ,function(err, docs){
    if(err) res.send({error:err});
    else res.send({data:docs, "Song":"song"});
  });
});
...

templates/song.hbs

...
{{#each model as |song|}}
  <li>
    <b>{{song.artist}} - {{song.title}}  {{#link-to 'edit' song.id}}EDIT{{/link-to}} </b><br>
    ID:<i>{{song._id}}</i> <br>
    Released: {{song.year}} <br>
    Genre: {{song.genre}} <br>
    Lyrics:<br> "{{song.lyrics}}"<br><br>
   </li>
{{/each}}
...

Here's my controllers/edit.js

...

export default Ember.Controller.extend({
  actions: {
    save: function() {
      var d = this.get('model');
      d.save();
      this.transitionToRoute('song');
    },
    del: function() {
      this.get('model').deleteRecord();
      this.transitionToRoute('song');
      this.get('model').save();
    }
  }
});
...

Upvotes: 0

Views: 2405

Answers (1)

num8er
num8er

Reputation: 19372

After getting GitHub link from You I saw that You've errors in code which leads to unknown behavior.

Simply replace app/routes.js with following content:

const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const SongsController = require('../api/songs');

const SongSchema = new mongoose.Schema({
  title: String,
  artist: String,
  year: Number,
  genre: String,
  lyrics: String
});

const Song = mongoose.model('song', SongSchema);

module.exports = (app) => {

  app.get('/api/songs', async (req, res) => {
    try {
      const songs = await Song.find({}).lean();
      res.status(200).send({songs});
    } catch(error) {
      res.status(500).send({
        message: error.message
      });
    }
  });

  app.get('/api/songs/:id', async (req, res) => {
    try {
      const song = await Song.findById(req.params.id).lean();
      if(!song) {
        return res.status(404).send({
          message: "Song not found",
          params: req.params
        });
      }
      res.status(200).send({song});
    } catch(error) {
      res.status(500).send({
        message: error.message
      });
    }
  });


  app.use(bodyParser.urlencoded({extended: false}));

  app.post('*', SongsController.addSong);
};

P.S. Quick fix is simply to pass handling to SongsController.findById method that already written:

app.get('/api/songs/:id', SongsController.findById);

Upvotes: 1

Related Questions