What is the best way to make changes to elements in an express array?

I have been developing an express application that enables users to manage a list of web projects through various HTTP methods such as get, post, put, and delete. So far, I have successfully implemented the logic for handling get, delete, and post requests with no issues. However, I am facing a challenge in allowing users to edit the information stored in the array.

const express = require('express');
const app = express();
const port = 8080;

app.use(express.json());

let webProjects = [
    {ID: 1, TITLE: "React Game", DESCRIPTION: "Tic tac toe game created using Create React App", URL: "http://heroku/myapp/game/"},
    {ID: 2, TITLE: "Online Store", DESCRIPTION: "Online store created with HTML, CSS and Javascript.", URL: "http://git.com/myrepos/shop/index"}
]

app.get('/api', (req, res) => {
    res.send(webProjects)
})

//the :id allows to capture a dynamic value in url
app.post('/api/:id/:title/:description/:url', (req, res) => {
    const { id } = req.params;
    const { title } = req.params;
    const { description } = req.params;
    const { url } = req.params;

    const bob = {ID:id, TITLE:title, DESCRIPTION:description, URL:url}
    webProjects.push(bob)

    res.send(webProjects)
});

app.delete('/api/:id', (req, res) => {
    const { id } = Number(req.params);
    const index = webProjects.indexOf(id)
    const deleteObj = webProjects.splice(index, 1)

    res.send(`The item was successfully deleted`)

})

app.put('/api/', (res, req) => {

})

app.listen(port , () => {
    console.log('Its working')
})

Answer №1

In my opinion, it is considered a best practice to receive data for PUT and POST requests through the request body. Only include the id of the item you wish to update in the URL as a parameter.

You can implement something along these lines:

app.put('/api/:id', (req, res) => {
  const projectId = parseInt(req.params.id);
  const { title, description, url } = req.body;
  const projectIndex = webProjects.findIndex(project => project.ID === projectId);

  if (projectIndex === -1) {
      return res.status(404).send("Project not found");
  }

  webProjects[projectIndex] = {
      ...webProjects[projectIndex],
      TITLE: title,
      DESCRIPTION: description,
      URL: url
  };

  res.send(webProjects);
});

Answer №2

A common mistake is using req.params to add data in the post API. A better practice is to utilize the body to retrieve the data you wish to insert into the array:

  app.post('/api', (req, res) => {
    const body = req.body;
    const projectData = {ID:body.id, TITLE:body.title, DESCRIPTION:body.description, 
    URL:body.url}
    webProjects.push(projectData)

    res.send(webProjects)
});

When it comes to updating, you must first locate the element you want to modify. Extract the ID from the params and use the PUT method.

   app.put('/api/:id', (req, res) => {
      const id = parseInt(req.params.id);
      const body = req.body;
      const indexToUpdate = webProjects.findIndex(project => project.ID === id);
    
      if (indexToUpdate === -1) {
          return res.status(404).send(`Project with this ${id} doesn't exist!`);
      }
    
      webProjects[indexToUpdate] = {
          ...webProjects[indexToUpdate],
          TITLE: body.title,
          DESCRIPTION: body.description,
          URL: body.url
      };

     res.send(webProjects);
});

Answer №3

It is essential to remember to update your delete route, as failing to do so could result in always deleting the last Project in the array.

app.delete('/api/:id', (req, res) => {
  const projectId = parseInt(req.params.id);
  const projectIndex = webProjects.findIndex(project => project.ID === projectId);

  if (projectIndex === -1) {
      return res.status(404).send("Project not found");
  }

  webProjects.splice(projectIndex,1);
//res.send(`The item was successfully deleted`)
  res.send(webProjects);
});

Answer №4

Take a look at this implementation:

const express = require("express");
const app = express();
const port = 6000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

let projects = [
  {
    ID: 1,
    TITLE: "React Game",
    DESCRIPTION: "Tic tac toe game developed using Create React App",
    URL: "http://someURL/myapp/game/",
  },
  {
    ID: 2,
    TITLE: "Online Store",
    DESCRIPTION: "E-commerce platform created with HTML, CSS and Javascript.",
    URL: "http://someURL2/shop/index",
  },
  {
    ID: 3,
    TITLE: "Online Store",
    DESCRIPTION: "Shopping website designed with HTML, CSS and Angular.",
    URL: "http://someURL3/shop2/index",
  },
];

app.get("/api", (req, res) => {
  res.send(projects);
});

app.put("/api/:id", (req, res) => {
  const id = req.params.id;

  const newData = req.body;
  let tempIndex = projects.findIndex((elem) => elem.ID == id);
  //database ID of the data to be updated
  let dB_ID = projects[tempIndex].ID;

  if (tempIndex > -1) {
    projects[tempIndex] = {
      ID: dB_ID,
      TITLE: newData.TITLE,
      DESCRIPTION: newData.DESCRIPTION,
      URL: newData.URL,
    };

    return res.status(200).json(projects[tempIndex]);
  } 

    return res.status(404).json({
      msg: "ID not found!",
    });
});

app.listen(port, () => {
  console.log("server is running on port: " + port);
});

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

Attempting to iterate through an array of HTML5 videos

Having some trouble with my video array - it plays but doesn't loop. I've tried using the HTML video attribute 'loop' and variations like loop="true" and loop="loop" without success. Tonight, all I want is for it to loop properly! var ...

How can I retrieve properties from a superclass in Typescript/Phaser?

Within my parent class, I have inherited from Phaser.GameObjects.Container. This parent class contains a property called InformationPanel which is of a custom class. The container also has multiple children of type Container. I am attempting to access the ...

Using a datepicker to calculate dates within a computed function in Vue

I'm currently exploring the most efficient method to dynamically generate fields based on date count or display a default option. Currently, I have successfully implemented the default setting of 11 days. However, my goal is to calculate the differen ...

What is the best way to convert a document.getElementById(id) element into a jQuery object?

It's surprising that no one has asked this question before: When I create elements using the following code: document.getElementById(id).innerHTML = (a string with id's in it); for example. I want to use jQuery to update the CSS of these dynam ...

Looking for MongoDB models based on date values?

In my Node.js mongodb application, I have a schema set up as follows: const calendarSchema = new Schema ({ title: String, start: String, //start date end: String, // end date endDate: String, sessionsRan: Number, _user: {type: Schem ...

Trouble displaying AngularJS $scope.data in the HTML code

I'm experiencing an issue where the data received from a POST request is being logged in the console, but is not displaying on the HTML page. Despite having a controller set up, the {{user}} variable is not appearing on the HTML page. While I can se ...

Unable to postpone the utilization of data in Vue until after retrieving the value from the database

I am facing an issue where I need to compare a string obtained from Firebase in document.check1 with specific strings (hardcoded in the function below) and display content accordingly. Currently, I know how to trigger this comparison on button click, but I ...

What could be causing the absence of any displayed content in FirBug when typing in the Google Search box?

Many websites with a suggestion box feature utilize AJAX requests to communicate with the server and receive responses. I attempted to intercept the requests made by the Google search box, but the FireBug console did not display anything. However, when us ...

Is it possible to update the variable value in one controller from another controller after an http.get request has been made

I have encountered an issue with updating a variable from one controller to another using a service. Despite my efforts, the variable is not being updated. The goal is to have the variable $scope.names in controller 'select' update in controller ...

Create a submit button using Vue.js for text input

Can anyone help with a beginner question? I have a form that includes a text field. When I type something in and press enter, no result shows up. However, when I type something in and click the button, I get the desired result. Could someone guide me on ...

Transform text that represents a numerical value in any base into an actual number

Looking to convert a base36 string back to a double value. The original double is 0.3128540377812142. When converting it to base 36: (0.3128540377812142).toString(36); The results are : Chrome: 0.b9ginb6s73gd1bfel7npv0wwmi Firefox: 0.b9ginb6s73e Now, h ...

Can I access the mongoose schema definition through swagger-jsdoc?

Recently, I completed a project using express.js with a MongoDB backend powered by mongoose. As I built the mongoose models through schemas, it crossed my mind whether there is a way to reference the schema definition instead of having to manually type out ...

To retrieve the first td element by clicking a button within the corresponding row using JQuery

This may seem like a straightforward inquiry, but despite my best efforts, I have been unable to find a solution. I am looking to create a function that will allow me to click a button located in the 3rd td element and display the text from the first td e ...

Creating the Apk file for your sencha touch application

Hello there! I'm diving into the world of Sencha Touch as a new user. After installing all the required tools and SDK, I successfully set up the demo example that came with project creation via command line. Now, I'm eager to generate the APK fil ...

Unable to retrieve innerHTML from a jQuery element

My current task involves implementing the Google Maps API. The code snippet below is what I have written so far: <div id="map"></div> To inspect the content of $("div#map"), I am utilizing the Google Chrome console. console.log($("div#map")) ...

A div positioned in front of a centrally-located div

Managing a website with numerous headlines can be a challenge. When a user clicks on a headline, a button located 10px to the left of the headline should appear. However, the catch is that the headlines must always remain centered, regardless of whether th ...

Iframe displaying a blank white screen following the adjustment of document.location twice

I am in the process of developing a web application that I intend to integrate into my Wix website. The main components of the required web application are a text screen and a button to switch between different screens/pages (html content). However, I am ...

What is the best way to position a div to float or hover from the bottom after it has been

I am working on creating a menu where clicking it will reveal a submenu at the bottom, but I'm encountering an issue. Currently, in my code, the submenu is appearing from right to left before moving down. Here is my code: <meta name="viewport" co ...

Creating a condensed version of the process: Utilizing jQuery for thumbnail preview on hover to create an image slideshow

I've created a video preview slideshow function using jQuery. As a newcomer to jQuery, I'm questioning if there's a more efficient way to achieve this. Having separate timers for each frame feels cumbersome and limits the flexibility in chan ...

Troubleshooting the Nextjs-blog tutorial loading issue on localhost:3000

Looking to delve into Nextjs, I decided to start by following a tutorial. However, every time I attempt to run 'npm run dev', the local host just keeps loading endlessly. Upon inspecting and checking the console, there is no feedback whatsoever. ...