Josué Venegas
Josué Venegas

Reputation: 39

Can not get data from controllers using Express NodeJS

I need to get data from two controllers, but when I call them, returns this error:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Plus, I want to know if I must write all the logic inside the try section. This is my code:

[UPDATED from Shariful Islam Mubin's reply]

DataMatching: controller that matches user tags and activities

const { response } = require('express');
const { userData } = require("./userData");
const { getActivities } = require("./activities");

const DataMatching = async (req, res = response) => {
  let userTags = [];
  let activities = [];
  let state = false;
  let topActivities= {};

  try {
    userTags = await userData(req, res);
    activities = await getActivities(req, res);

    if (userTags.data.tags && activities){
     userTags = userTags.data.tags;
     state = true;
     //doSomething
    }
    return res.json({
      ok: state,
      response: topActivities
    });
  }
  catch (error) {
    return res.status(500).json({
    ok: state,
    response: error
    });
  }
}

module.exports = {
  DataMatching
}

userData: controller that gets user data

const { response } = require('express');
const axios = require('axios');

const userData = async (req, res = response) => {
  try {
    let res_user = await axios.get(somePath, someConfig)

    if (res_user.data.success === true) {
      return res.json({
        ok: true,
        response: res_user.data
      })
    } else {
      return res.status(500).json({
        ok: false,
        error: res_user.data.message
      })
    }
  } catch (error) {
    return res.status(500).json({
      ok: true,
      response: res_user
    })
  }
}

module.exports = {
  userData
}

getActivities: controller that gets activities data

const { response } = require('express');
const Activity = require('../models/activity');

const getActivities = async (req, res = response) => {
  const activities = await Activity.find().populate('tags')

  try {
    return res.json({
      ok: true,
      activities
    });
  }
  catch (error) {
    return res.status(500).json({
      ok: false,
      error: error
    });
  }
}

Upvotes: 0

Views: 99

Answers (1)

Shariful Islam Mubin
Shariful Islam Mubin

Reputation: 2286

As soon as you call res object, you must have to return it. Because, res or response object sends data to the client. And you cannot return anything after sending a response to the client.

So, you've to write

return res.json({/*.. YOUR_CODE_GOES_HERE ..*/})

and,

return res.status(500).json({/*.. YOUR_CODE_GOES_HERE ..*/})

I also noticed you called other 2 functions which are also responsible for responding to the client. You shouldn't do that.

  • Try to return response only from the requested controller, which may be DataMatching function in this case.
  • Youu can wrap all code inside DataMatching function in a try-catch block to handle any exception that occurs in the function.

Upvotes: 1

Related Questions