hapipal / examples

A place to find example projects built using hapi pal
5 stars 3 forks source link

500 Error on getting-started tutorial Database part #1

Closed zhzhang2018 closed 6 years ago

zhzhang2018 commented 6 years ago

Hi, I was following this tutorial: https://hapipal.com/getting-started#querying-our-database At the last step, where we try to add an entry to the database, we received the following error on the terminal window hosting the server:

node server

Server started at http://0.0.0.0:3000 Debug: internal, implementation, error TypeError: Cannot read property 'query' of undefined at handler (/.../riddle/lib/routes/riddle-create.js:29:34) at module.exports.internals.Manager.execute (/.../riddle/node_modules/hapi/lib/toolkit.js:35:106) at Object.internals.handler (/.../riddle/node_modules/hapi/lib/handler.js:52:48) at exports.execute (/.../riddle/node_modules/hapi/lib/handler.js:37:36) at module.exports.internals.Request._lifecycle (/.../riddle/node_modules/hapi/lib/request.js:261:62) at at process._tickCallback (internal/process/next_tick.js:182:7)

And the other terminal window with the curl command returned the 404 message: curl -H "Content-Type: application/json" -X POST -d '{"slug":"plug","question":"Why?","answer":"Because reasons"}' http://0.0.0.0:3000/riddle-create {"statusCode":404,"error":"Not Found","message":"Not Found"}

Do you have any suggestion on how to proceed from here?

Update: I have tried changing "insertAndFetch" in riddle-create.js into "insert", but still no luck. Using "console.log" to print "riddle" worked perfectly.

devinivy commented 6 years ago

The curl likely failed with a 404 because the URL doesn't match your route's path. I assume the path is /riddle and not /riddle-create—possibly just a typo in the tutorial.

As for the other error Cannot read property 'query' of undefined, it sounds like your Riddles variable is undefined. Is that model already in place? Is it possibly just a capitalization issue, i.e. Riddle versus Riddles? You can see which models are available (by name/key) by logging console.log(Object.keys(request.models())).

Good luck!

zhzhang2018 commented 6 years ago

Hi, I used /riddle and it still didn't work -- the error seems to lie in the query in Objection. The full code that I used in riddle-create.js is:

'use strict';

const Joi = require('joi');

module.exports = { method: 'post', path: '/riddle', options: { validate: { // Check that the POST'd data complies with our model's schema payload: { slug: Joi.string().required(), question: Joi.string().required(), answer: Joi.string().required() } }, // Our db query is asynchronous, so we keep async around this time handler: async (request, h) => {

        // We nab our Riddles model, from which we execute queries on our Riddles table
        const { Riddles } = request.models();

        // We store our payload (the prospective new Riddle object)
        const riddle = request.payload;
        console.log(riddle);

        // We try to add the POST'd riddle using Objection's insertAndFetch method (http://vincit.github.io/objection.js/#insertandfetch)
        // If that throws for any reason, hapi will reply with a 500 error for us, which we could customize better in the future.

        //return await Riddles.query().insertAndFetch(riddle);
        await Riddles.query().insertAndFetch({
            slug: 'wtf',
            question: 'bug',
            answer: 'smash computer'
        });
    }
}

};

I think Riddles should be defined, but console.log only printed "['ModelName']".

devinivy commented 6 years ago

Ah, we've narrowed it down! The name of the model comes from its class name. hpal make model does not current set the class name—just the file name. If you go into lib/models/Riddles.js you can make this change,

 'use strict';

 const Schwifty = require('schwifty');
 const Joi = require('joi');

-module.exports = class ModelName extends Schwifty.Model {
+module.exports = class Riddles extends Schwifty.Model {

     static get tableName() {

         return 'Riddles';
     }
zhzhang2018 commented 6 years ago

OK, it's working now. But when I entered the slug value after "http://0.0.0.0:3000/riddle-answer/" after insertion, the display is still 404...

devinivy commented 6 years ago

Does your /riddle-answer route look-up data from the database or from somewhere else?

zhzhang2018 commented 6 years ago

I think it's using the data.js file, which is hardcoded. Perhaps I should try to find a tutorial on how to link to the database. Right now I'm trying to add swagger, but turned every route into 404s...

zhzhang2018 commented 6 years ago

We figured out that it's because disabling data.js makes the database initially empty. After adding one query it worked fine. The problem is the riddle-random page is showing the entire entry instead of just the riddle.

TiaTalks commented 6 years ago

We figured it out, sorry

devinivy commented 6 years ago

Glad you got it! :) I'm closing this issue out, but if you have any more general-purpose questions https://github.com/hapipal/discuss is a good place to ask!