Reputation: 23
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
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