using conditional statements in an app.get() method in express js

app.get('/api/notes/:id', (req, res, next) => {
  fs.readFile(dataPath, 'utf-8', (err, data) => {
    if (err) {
      throw err;
    }
    const wholeData = JSON.parse(data);
    const objects = wholeData.notes;
    const inputId = parseInt(req.params.id);

    if (inputId <= 0) {
      res.status(400).json({error: 'id must be a positive integer'});
    } else {
      let found = false;
      for (const key in objects) {
        if (parseInt(objects[key].id) === inputId) {
          found = true;
          res.status(200).json(objects[key]);
          break;
        }
      }
      if (!found) {
        res.status(404).json({error: `Oops! There is no id ${inputId}`});
      }
    } 
    
  })
  
})

This is the code I have implemented so far. I have set this globally:

const dataPath = 'data.json';

Here is what the content of the data.json file looks like:

{
  "nextId": 5,
  "notes": {
    "1": {
      "id": 1,
      "content": "The event loop is how a JavaScript runtime pushes asynchronous callbacks onto the stack once the stack is cleared."
    },
    "2": {
      "id": 2,
      "content": "Prototypal inheritance is how JavaScript objects delegate behavior."
    },
    "3": {
      "id": 3,
      "content": "In JavaScript, the value of 'this' is determined when a function is called; not when it is defined."
    },
    "4": {
      "id": 4,
      "content": "A closure is formed when a function retains access to variables in its lexical scope."
    }
  }
}

When I run the command http -v get :3000/api/notes/3 in the terminal, the error message gets triggered instead of returning the object with id 3.

However, if I remove the error message if statement, the code successfully retrieves the object from the JSON file. How can I solve this issue?

Answer №1

The issue you have encountered

_http_outgoing.js:470 throw new ERR_HTTP_HEADERS_SENT('set'); ^ Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

occurred because res.json() is being used within a for...in loop. The first iteration causes subsequent iterations to fail as it sends a response.

The res object represents the HTTP response that an Express app sends when it receives an HTTP request.

To resolve this, manipulate the data (object/array/collection) inside the loop and send it outside of the loop.

You can implement something like this:

app.get('/api/notes/:id', (req, res, next) => {
  fs.readFile(dataPath, 'utf-8', (err, data) => {
    if (err) {
      throw err;
    }
    const wholeData = JSON.parse(data);
    const objects = wholeData.notes;
    const inputId = parseInt(req.params.id);

    if (inputId <= 0) {
      res.status(400).json({error: 'id must be a postive integer'});
    } else {
      let obj= false;
      for (const key in objects) {
        if (parseInt(objects[key].id) === inputId) {
          obj = objects[key];
        }
      }
      if (obj) {
        res.status(200).json(obj)
      } else 
        res.status(404).json({error: `bruh theres no id ${inputId}`})
      }
    }
  });
  
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The radio button fails to trigger the setState function in React

In my React program, I have implemented a method to update the state and modify a specific value for a Radio button: The state : class App extends Component { constructor(props) { super(props); this.state = { checked: [], expanded: [], ...

How to dynamically generate Angular component selectors with variables or loops?

Looking to dynamically generate the Selector Tag in my app.component.html using a variable. Let's say the variable name is: componentVar:string What I want in my app.component.html: <componentVar></componentVar> or <app-componentVar& ...

The call stack limit has been exceeded in VueJS/VueX

I'm currently developing a Vue project with Vuex for state management. However, I encountered a Maximum call stack size exceeded error in my console when attempting to bind actions and getters in my component using mapActions and mapGetters. I'm ...

Saving the Structure of an XML Document Using JQuery

Xml: <Data> <Cat> <Name>Fluffy</Name> </Cat> <Cat> <Name>Willy</Name> </Cat> </Data> JQuery: // ...Executing ajax requests... $(xml).find('Cat').each(function ...

What is the proper way to convert nil to JSON as nil, without representing it as an empty value?

I'm facing an issue in my controller/action where some values turn out to be nil: def my_action @var1 = get_boolean_value || nil @var2 = get_int_value || nil @var3 = get_string_value || nil # there are many more values, any of them might be ...

JavaScript encoding the text

Looking for a straightforward JavaScript function to encrypt text data from a textarea using a key (the key being the user's password stored as a hashed session variable, outputted by PHP into a field). The objective is to have the content of the tex ...

The Material UI button feature neglects to account for custom CSS styles when attempting to override the default settings

Utilizing a custom bootstrap css styles in my react app, I am seeking to enhance the default material ui components with the bootstrap styles. import React, {useState} from 'react'; import 'cg-bootstrap/core/build/cg-bootstrap-standard.css&a ...

Encountering an issue with Server Side Rendering in React Router Dom where an error message pops up saying: "Warning: React.createElement: type is

Specific Error: A warning has occurred: React.createElement: the type provided is invalid -- it was expecting a string (for built-in components) or a class/function (for composite components), but instead received an object. in Posts in Connect(Po ...

Angular JS has a unique feature of a scrollable drop-up menu that allows

Here is the code snippet for my Dropup component: <div class="dropup"> <button class="btn btn-primary btn-raised dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false> ...

Should we consider using extra url query parameters as a legitimate method to avoid caching or enforce the updating of css/js files?

Is it acceptable to include extra URL query parameters in order to avoid caching or enforce the updating of CSS/JS files? /style.css?v=1 Or would it be preferable to rename the file/directory instead? /style.1.css I've heard that this could potent ...

Adjusted position of the viewport if the DOM element containing the renderer is not located at the top of the display

I've come across an issue with a three.js scene within an Angular custom directive in the view. At the top, there's a navigation bar for switching between views (pretty standard so far). I set up a simple scene with a cube and basic camera rotati ...

Providing the module with the URL

How can I retrieve the URL within a module? module.exports = function(app, Reviews, Anon, User, url){ var url = url; console.log("url", url)// url is undefined how to get url function postHandler(req, res){ } app.post("/individual/"+ u ...

Combining for loops and async waterfall for optimal efficiency

Hey there, I'm just starting out with Nodejs and could really use some advice on writing more efficient code. Let me explain my issue. So, I have this function that is utilizing an async waterfall model. My goal is to call this function within a loop ...

Synchronizing the DOM with the Database in a React Component/View: A Step-by-Step

I recently developed a list component in React, but I'm facing two significant challenges. Although the item gets removed from the database, the change is only visible after refreshing the page. You might have noticed that the list number or ID colu ...

When you press the back button and navigate to a different page, the scroll position will remain unchanged

I'm facing an issue with scrolling on my angularjs app. Currently, the app consists of 2 pages: The first page displays a list of customers, where you can select one to view their details. The second page is a list of companies, following a similar s ...

"Utilize Cypress to simulate clicking a button by triggering the enter key

Currently, I'm conducting testing on my application and attempting to trigger a button click using the Enter key: <v-btn class="submit-button" block color="primary" @click="login" > Log In < ...

Warning: Nodejs has reached the maximum number of listeners allowed

I've encountered an issue that pops up occasionally and I'm not sure how to troubleshoot it. Here's the error message: (node:9140) MaxListenersExceededWarning: Possible EventEmitter memory leak detec ted. 11 error listeners added. Use emit ...

"Optimizing npm packages for front-end web development in vanilla JavaScript: A guide to bundling for production deployments on

My website is built using vanilla HTML/CSS/JavaScript with ES6 modules and can be deployed to GitHub pages and Netlify. I have set up my site by importing "main.js" in my HTML like this: <script src="js/main.js" type="module" defer&g ...

Retrieve a zip file using React and Node from a RESTful API

I have an application built with React and Node where I have a table that includes a download button. Clicking the download button triggers a request to my Node app, which in turn should call a REST API to download a zip file directly into the browser. In ...

Trouble with binding to an array inside a Vue component instance

Trying to grasp the concepts of vue.js, but struggling with a crucial element. The goal is to create an accordion functionality for multiple boxes (only one box displayed at a time; opening a new box closes any previously open ones). Here's the curre ...