iEmad
iEmad

Reputation: 625

Display response from HTTP request hapi.js 17.2.0

I'm trying to display a page using the new HapiJS 17 but it has dependency on http request. So basically I consume a rest API then a return it to the new response toolkit aka 'h toolkit' but it gives error in the console

Error: handler method did not return a value, a promise, or throw an error

It also gives a browser error

An internal server error occurred

{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"}

Below is my code (I tried to make it as simple as possible without handling errors and so on for sake of simplicity)

'use strict';

const Hapi = require('hapi');
const Request = require('request');

const server = Hapi.server({ 
  host: '127.0.0.1', 
  port: 8000,
  router: { stripTrailingSlash: true }
});

//Fix double slash issue
server.ext({
  type: 'onRequest',
  method: function (request, h) {
    var path = request.url.path.replace(/\/\//,'/');
    request.setUrl(path);
    return h.continue;
  }
});

server.route({
  method: 'GET',
  path:'/',
  handler: function (request, h) {
    return h.response('Welcome to HapiJS');
  }
});

server.route({
  method: 'GET',
  path:'/a',
  handler: function(req, h) {
    Request
      .get('https://httpbin.org/ip')
      .on('data', function(data) {
        return h.response('data:' + data);
      });
  }
});

server.start();

FYI, same thing work in Express without any issues (I'm guessing it would work with HapiJS 16 as well

const Express = require('express');
const Request = require('request');
const app = Express();
const port = "8000";

app.get('/', function(req, res, next) {
  res.send('Hello world');
});

app.get('/a', function(req, res, next) {
  Request
    .get('https://httpbin.org/ip')
    .on('data', function(data) {
      res.send('data:' + data);
    });
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

I found this example with HapiJS 16

http://www.eloquentwebapp.com/comsume-restful-api/

Upvotes: 1

Views: 2172

Answers (2)

Harish Gupta
Harish Gupta

Reputation: 40

Since, HapiJs v17.x is based on async/await. Use const Request = require('request-promise');

Request-Promise: https://github.com/request/request-promise

Code changes to the following:

server.route({
method: 'GET',
path:'/a',
handler: async function(req, h) {
  let response = await Request.get('https://httpbin.org/ip');
  return response;
 }
});

Upvotes: 2

HMR
HMR

Reputation: 39310

The error suggests you should return a promise of h.response like so:

server.route({
  method: 'GET',
  path:'/a',
  handler: (req, h) =>
    new Promise(
      (resolve,reject)=> 
        Request
        .get('https://httpbin.org/ip')
        .on('data', function(data) {
          resolve(h.response('data:' + data));
        })
    )
});

This only work with Hapi.js 16

However; according to the documentation you don't have to return anything and can do something like this:

server.route({
  method: 'GET',
  path:'/a',
  handler: (req, res) =>
    Request
    .get('https://httpbin.org/ip')
    .on('data', function(data) {
      res('data:' + data);
    })
});

Upvotes: 3

Related Questions