Home > Enterprise >  How to dynamically adjust the content of the PATCH method?
How to dynamically adjust the content of the PATCH method?

Time:10-02

I'm trying to build a REST API with NodeJS, ExpressJS and Prisma. At the moment, when I want to update a user through the PATH method, I do this:

const data = {}

if (req.body.email != null)
    data.email = req.body.email
if (req.body.password != null)
    data.password = req.body.password
if (req.body.first_name != null)
    data.first_name = req.body.first_name
if (req.body.last_name != null)
    data.last_name = req.body.last_name

await prisma.user.update({
    where: {
        id: parseInt(id)
    },
    data: data
})

I removed the unnecessary code to show you the essential things.

I think this is not the best option, is there an easier way to do the same thing? I've tried a few solutions but none of them work with Prisma, that's why I'm here.

CodePudding user response:

You could make a helper function to make the code less repetitive

Something like

const copyProps = (src, ...keys) =>
  Object.fromEntries(
    Object.entries(src)
    .filter(([k,v]) => keys.includes(k) && v != null)
  );

Then you can use it like

await prisma.user.update({
    where: {
        id: parseInt(id)
    },
    data: copyProps(req.body, 'email', 'password', 'first_name', 'last_name');
});

CodePudding user response:

You could make yourself a function that copies properties that meet some condition:

function copyNamedPropsWithData(props, src, target = {}) {
    for (let prop of props) {
        if (src[prop] != null) {
            target[prop] = src[prop];
        }
    }
    return target;
}

and then use that function:

const validProps = ["email", "password", "first_name", "last_name"];
await prisma.user.update({
    where: {
        id: parseInt(id)
    },
    data: copyNamedPropsWithData(validProps, req.body)
})

This allows you to create a new sterile object that contains only the non-empty properties that you list. It keeps you from specifying empty properties and it blocks other properties that aren't in your named list. I end up using something like this in nearly every project because it's an important part of sterlizing data coming from an unknown source to only contain the fields you want it to contain.

  • Related