Renato Zanotelli
Renato Zanotelli

Reputation: 63

How to use PATCH with Node.js and Express

initially I use a post on the route (POST / territories)

app.post('/territories', (req, res, next) => { // Cria um produto
    
    const territories = bancoDeDados.salvarTerritorie({
        data:{
        nome : req.body.name,
        inicio : {x : req.body.inicio, y : req.body.inicio},
        fim : { x : req.body.fim, y : req.body.fim},
        área : req.body.fim * req.body.fim,
        pintado_área :  0,
        }        
    },req.body.fim);

    res.send(territories)
})

this route returns me:

{
    "data": {
        "nome": "potato",
        "inicio": {
            "x": "0",
            "y": "0"
        },
        "fim": {
            "x": "5",
            "y": "5"
        },
        "área": 25,
        "pintado_área": 0
    },
    "id": 1
}

Then I need to use the route (GET / squares /: x /: y) to access a specific index of the matrix (one of the mini squares in the giant square). With this route I get:

{
  "data": {
    "x": 1,
    "y": 2,
    "painted": false  
  },
  "error": false
}

My goal is to change the '' painted '' from false to true, using the PATCH route (/ squares /: x /: y / paint) when entering this route, I get:

{
  "data": {
    "x": 1,
    "y": 2,
    "painted": true
  },
  "error": false
}

however when I return with GET (/ squares /: x /: y) to check if it remains painted, I get false again.

I'm not having successful in this change, I was able to make the PATCH deliver myself as True, however when calling GET again to check, I get False. Does anyone know how to solve?

** EDIT **

Follow my Patch route:

app.patch('/squares/:x/:y/paint', (req, res, next) => {
    const x = req.params.x
    const y = req.params.y

    res.send({
        painted : true
    })
})

I get the following value from it:

{
    "painted": true
}

EDIT 16/12 01:47

My post route it creates this Matrix, along with a sequential ID.

function salvarTerritorie(territorie,area) { //Define o Id seguinte para o territorie ou utiliza um ID definido caso tenha
    if (!territorie.id) territorie.id = sequence.id
    territories[territorie.id] = territorie
    
    var MATRIZ2 = [];
    for (var i = 0; i < area; i++) {
        MATRIZ2[i] = [];
        for (var j = 0; j < area; j++) {
            MATRIZ2[i][j] = ''
        }
    }

    for (var L = 0; L < area; L++) {
        for (var C = 0; C < area; C++) {
            
            MATRIZ2[L][C] = {
                data: {
                  x: L,
                  y: C,
                  painted: false  
                },
                error: false
              }
        }
    }

I tried to reuse the code you sent me:

app.patch('/squares/:x/:y/paint', (req, res, next) => {
    const x = req.params.x
    const y = req.params.y
    const changes = req.body;

    const originalInformation = bancoDeDados.retrieveOriginalInformationInMatrix(x, y);
    // originalInformation will be {"x": 1, "y": 2, "painted": false }

    let modifiedInformation = originalInformation
    if (changes.painted !== undefined) {
        modifiedInformation.painted = true // Updates new information with desired changes
    }
    // Other possible changes like changes.x or changes.y

    res.send(modifiedInformation); // Returns modified information back to user
})

I created a function with the name of the function you gave:

function retrieveOriginalInformationInMatrix(x,y){
    const stringQuadrado = JSON.stringify(territories.matriz)
    const dadosQuadrado = JSON.parse(stringQuadrado)
    return dadosQuadrado[x][y].data.painted = true
}

When using Patch, I am getting exactly a single "true" message.

checking the get again, false remains unchanged.

EDIT 16/12 02:41

I got a breakthrough thanks to the help I'm getting, I managed to make him insert a new painted simultaneously, but I couldn't change the value of the existing one. With the function passed on by IcyBloom:

app.patch('/squares/:x/:y/paint', (req, res, next) => {
    const x = req.params.x
    const y = req.params.y
    const changes = req.body;
    const originalInformation = bancoDeDados.retrieveOriginalInformationInMatrix(x, y);
    // originalInformation will be {"x": 1, "y": 2, "painted": false }
    let modifiedInformation = originalInformation
    if (changes.painted !== undefined) {
        modifiedInformation.data.painted = true // Updates new information with desired changes
    }
    // Other possible changes like changes.x or changes.y
    res.send(modifiedInformation); // Returns modified information back to user
})

I am getting the following result:

{
    "data": {
        "x": 4,
        "y": 4,
        "painted": false
    },
    "error": false,
    "painted": true
}

I need to change the existing painted one instead of creating a new one. But I'm not getting it.

Upvotes: 6

Views: 39617

Answers (1)

IcyBloom
IcyBloom

Reputation: 340

So together with my comment, here's a rough example of how your PATCH API should look like

app.patch('/squares/:x/:y/paint', (req, res, next) => {
    const x = req.params.x
    const y = req.params.y
    const changes = req.body;

    const originalInformation = retrieveOriginalInformationInMatrix(x, y);
    // originalInformation will be {"x": 1, "y": 2, "painted": false }

    let modifiedInformation = originalInformation
    if (changes.painted !== undefined) {
        modifiedInformation.painted = changes.painted // Updates new information with desired changes
    }
    // Other possible changes like changes.x or changes.y
    saveModifiedInformation(x, y, modifiedInformation);

    res.send(modifiedInformation); // Returns modified information back to user
})

You might be wondering what req.body is. When sending a PATCH request, its much like your POST request where the changes are in the request body. So in the example above, my envisioned req.body will be:

{
    "painted": "true"
}

Edit: Try modify your retrieveOriginalinformationInMatrix function as such

function retrieveOriginalInformationInMatrix(x,y){
    const stringQuadrado = JSON.stringify(territories.matriz)
    const dadosQuadrado = JSON.parse(stringQuadrado)
    return dadosQuadrado[x][y]
}

This should return {"x": 1, "y": 2, "painted": false }

Next, insert this function into the original example (see above, I have added it in already):

function saveModifiedInformation(x, y, modifiedInformation) {
    territories.matriz[x][y] = modifiedInformation
}

Upvotes: 3

Related Questions