outmoded / discuss

The "mailing list"
99 stars 9 forks source link

Calling server method in pre handler using string notation gives error method.call is not a function in Hapijs 17.0.1 #575

Closed saurabhghewari closed 5 years ago

saurabhghewari commented 6 years ago

Hi Hapi Team,

I am using Hapijs for developing large projects for my company and would like to continue the same for comming projects.

Right now I am facing some issues migrating from Hapi 16 to Hapi 17. Below is the code

Server.js

const Hapi = require('hapi');
const server = Hapi.server({ host: 'localhost', port: 8000 });

server.events.on('route', (route) => {
    console.log(route.path);
});

(async function() {

    await server.register([{plugin : require('./user')}]);

    await server.start();

    console.log("Server is listening on " + server.info.uri);
})();

User Plugin:-

index.js

   'use strict';

module.exports = {
    name: 'user-plugin',
    version: '1.0.0',
    register:  (server, options) =>  {
        let methods = require('./user_methods');
        server.method(methods(server, options));
        let routes = require('./user_routes');
        server.route(routes(server, options));
    }
}

user_routes.js

'use strict';

const Config = require('./user_config');

module.exports = function() {
    return [
        {
            path: "/users/create",
            method: "POST",
            options: Config.create
        }
    ];
}

user_config.js

'use strict'

const Handlers = require('./user_handler');

module.exports = {

    create : {
        pre: [
            { method : "user.create(payload)", assign : 'createUser' }
        ],
        handler : Handlers.createUser
    }
}

user_methods.js

'use strict';

const createUser = function createUser(payload) {

    console.log("Payload received = ", payload);

    return payload;
}

module.exports = (server, options) => [
    {
        name : "user.create",
        method : createUser,
        options : {
            bind : server
        }
    }
]

user_methods.js

'use strict';

module.exports = {
    createUser: (request, h) => { return request.pre.createUser }
}

============================================================= Code Ends

The above code throws error

Debug: internal, implementation, error TypeError: method.call is not a function at module.exports.internals.Manager.execute (/home/saurabh/node_spikes/hapi_17/node_modules/hapi/lib/toolkit.js:42:106) at Object.internals.handler (/home/saurabh/node_spikes/hapi_17/node_modules/hapi/lib/handler.js:52:48) at exports.execute (/home/saurabh/node_spikes/hapi_17/node_modules/hapi/lib/handler.js:22:37) at internals.Request._lifecycle (/home/saurabh/node_spikes/hapi_17/node_modules/hapi/lib/request.js:276:62) at at process._tickCallback (internal/process/next_tick.js:188:7)

Hapijs version:- 17.0.1 Nodejs:- 8 Boilerplate: https://github.com/franzip/generator-hapi-api-stack

The same code with some changes in server.js file and hapijs version 16 works perfectly. I am pretty sure the error is at user_config.js -> pre handler -> "user.create(payload)". Please help me in solving this as I need to migrate my code base from Hapijs 16 to Hapijs 17.

Marsup commented 6 years ago

Remove handler and pre server method string shortcut support. ⬅️ it's in the changlog. Arrow functions are about as long as the string version so it's deprecated.

saurabhghewari commented 6 years ago

Oh, Thank you for the information and also for lightning fast response.

So, according to the change log I need to use request.server.methods.methodName(param1, param2, ...) in pre handler and then return the response.

Thank you once again.

Marsup commented 6 years ago

In other words { method : "user.create(payload)", assign : 'createUser' } should likely become { method : (request) => request.server.methods.user.create(request.payload), assign : 'createUser' }.

saurabhghewari commented 6 years ago

Oh, great that helped me. Thank you very much.