samedi 27 décembre 2014

Can't use resourceId from the view in a little application developed with MEAN stack


I am trying to build a little sample app to learn the MEAN stack.


This is what I am trying to achieve:



GET /quizes - returns quizes
POST /quizes - create a quiz
GET /quizes/:quizId - return the quiz with id quizId

GET /quizes/:quizId/questions - returns all the questions for the quiz with id quizId
POST /quizes/:quizId/questions - Create a new question for the quiz with id quizId


I do not have any problem with the 3 first routes, I can list quizes, create and update one.


The problems start for the questions. I think that I am not passing the quizId properly.


Here is my code:


This is the view I am using to view a quiz. There is no problem there, except that when I do click one of the links at the bottom (respectively to view the questions for that quiz, or to create a new question), I have an error in the console (I will paste it right under the view).


Important: This is the view that I will see, according to the routes I have configured, when I am on the url http://localhost:3000/api/quizes/1234 (1234 being the id of the quiz).



<section data-ng-controller="QuizesController" data-ng-init="findOne()">
<h1 data-ng-bind="quiz.title"></h1>
<div data-ng-show="authentication.user._id == quiz.creator._id">
<a href="/#!/quizes/{{quiz._id}}/edit">edit</a>
<a href="#" data-ng-click="delete();">delete</a>
</div>
<small>
<em>Posted on</em>
<em data-ng-bind="quiz.created | date:'mediumDate'"></em>
<em>by</em>
<em data-ng-bind="quiz.creator.fullName"></em>
</small>
<p data-ng-bind="quiz.description"></p>
id: {{quiz._id}}
<li><a href="/#!/quizes/{{quiz._id}}/questions">List Questions</a></li>
<li><a href="/#!/quizes/{{quiz._id}}/questions/create">Create Question</a></li>
</section>


The error I have in the console when clicking one of the links:



**GET http://localhost:3000/api/quizes/questions 500 (Internal Server Error)**


I noticed here that the URL is wrong, it should not be /api/quizes/questions, it should be /api/quizes/1234/questions if I do try to list the questions. I am missing something?


This is the routes for the /api/quiz/:quizId/questions route and such:



var users = require('../../app/controllers/users.server.controller'),
questions = require('../../app/controllers/questions.server.controller'),
quizes = require('../../app/controllers/quizes.server.controller');

module.exports = function(app) {
app.route('/api/quiz/:quizId/questions')
.get(questions.list)
.post(users.requiresLogin, questions.create);

app.route('/api/quizes/:quizId/questions/:questionId')
.get(questions.read)
.put(users.requiresLogin, questions.hasAuthorization, questions.update)
.delete(users.requiresLogin, questions.hasAuthorization, questions.delete);

app.param('quizId', quizes.quizByID);
app.param('questionId', questions.questionByID);

};


This is the Question Controller on the server side: (I removed the add/update/delete function etc...):



var mongoose = require('mongoose'),
Question = mongoose.model('Question');

exports.create = function(req, res) {
var question = new Question(req.body);
question.creator = req.user;
question.quiz = req.quiz;

question.save(function(err) {
if (err) {
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
res.json(question);
}
});
};

exports.list = function(req, res, quizId) {
Question.find({quiz: quizId}).sort('-created').populate('creator', 'firstName lastName fullName').exec(function(err, questions) {
if (err) {
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
res.json(questions);
}
});
};

exports.questionByID = function(req, res, next, id) {
Question.findById(id).populate('creator', 'firstName lastName fullName').exec(function(err, question) {
if (err) return next(err);
if (!question) return next(new Error('Failed to load question ' + id));

req.question = question;
next();
});
};


This is the service:



'use strict';

angular.module('questions').factory('Questions', ['$resource', function($resource) {
return $resource('api/quizes/:quizId/questions/:questionId', {
questionId: '@_id'
}, {
update: {
method: 'PUT'
}
});
}]);


Finally, this is the controller on the client side (I also removed update and delete for more clarity):



'use strict';

angular.module('questions').controller('QuestionsController', ['$scope', '$routeParams', '$location', 'Authentication', 'Questions', 'Quizes',
function($scope, $routeParams, $location, Authentication, Questions, Quizes) {
$scope.authentication = Authentication;

$scope.create = function() {
var question = new Questions({
value: this.value,
type: this.type,
answer: this.answer
});

question.$save(function(response) {
$location.path('quizes/:quizId/questions/' + response._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};

$scope.find = function() {
$scope.questions = Questions.query();
};

$scope.findOne = function() {
$scope.question = Questions.get({
questionId: $routeParams.questionId
});
};
}
]);




Aucun commentaire:

Enregistrer un commentaire