Diesan Romero
Diesan Romero

Reputation: 1658

Why h.response return a string instead of object on HapiJS?

I am creating an API with HapiJS, using TDD I am receiving an error because the test validates the payload of the request, curiously, I receive a string instead of an object as the documentation says.

This is my test written with @hapi/lab:

it('payload should be a json object', async () => {
    const res = await server.inject({
      method: 'GET',
      url: '/users'
    })
    console.log(res)
    expect(res.payload).to.be.object()
  })

and this is my route:

server.route({
  method: 'GET',
  path: '/users',
  handler: (request, h) => {
    const data = {
      message: 'App'
    }

    const response = h
      .response(data)
      .type('application/json')
      .header('content-type', 'application/json')
      .code(200)
    
    return response
  }
})

By the way, that console.log in the test is to confirm the content of the res.payload and verify that it was receiving a string instead of an object.

This is the specific error I get from the test: Expected '{"message":"App"}' to be an object but got 'string'

Upvotes: 2

Views: 1211

Answers (1)

Jonas Pauthier
Jonas Pauthier

Reputation: 511

The property you are looking for is result on the response object you get from inject method.

payload is the data from the endpoint as hapi would send to the client, meaning it was serialized. That's the reason you get a string. Instead the result property is the raw data returned from the endpoint before serialization. You can find more information in the documentation in the return section.

Here is a code snippet to showcase this:

const Hapi = require("@hapi/hapi");

const server = Hapi.Server();

server.route({
  method: "GET",
  path: "/test",
  options: {
    handler(req, h) {
      return { result: 1 };
    },
  },
});

(async function () {
  await server.start();

  console.log("server started");

  const res = await server.inject({
    method: "GET",
    url: "/test",
  });

  console.log(res.payload); // ==> '{"result": 1}'
  console.log(res.result); // ==> { result: 1 }
})();

Also to answer one of the comment you made, you actually already sent an object from your hapi server. It's just that the data was serialized. You'd need to deserialize it in whatever context you'd be calling your endpoint, with JSON.parse() for example, before you could use it.

Upvotes: 3

Related Questions