0

I have an API call to get all the users of my application. I have a problem, that the getAll method returns each users's password encrypted. I don't want to return the password.

That's my method:

async getAll(pagination) {
    try {
      const { UserAdmin: userAdminSchema } = this.getSchemas();
      let usersAdmins = await userAdminSchema.paginate({}, {
        sort: { created: 'desc' },
        limit: pagination.limit ? parseInt(pagination.limit) : 10,
        page: pagination.page ? parseInt(pagination.page) + 1 : 1,
      });
      if (!usersAdmins) {
        throw new errors.NotFound('No UserAdmins found.');
      }
      usersAdmins.docs.map(async (u) => {
        delete u.password;
      });
      return usersAdmins
    } catch (error) {
      throw error;
    }
{
  "docs": [
    {
      "roles": [
        "Admin",
        "Read",
        "Modify",
      ],
      "_id": "5ffecc12a687a30580239a10",
      "name": "john",
      "email": "[email protected]",
      "password": "$2a$10$K6oKiiWKsIWmAGgkG7TmH.WjVpraNg45Uc0nber3FnF26oEzdgTS2",
      "created": "2021-01-13T10:31:46.982Z",
      "__v": 0
    },
    {
      "roles": [
        "Read"
      ],
      "_id": "5ffea1f1dd60b80718af6e3b",
      "name": "Megan",
      "email": "[email protected]",
      "password": "$2a$10$V8ARIjxhEHCC1COcvtQEmOZ3IfXm5oiANdLmyHyipy1GmWSD3ctWK",
      "created": "2021-01-13T07:32:01.665Z",
      "__v": 0
    },
  ],
  "totalDocs": 2,
  "limit": 10,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": 1,
  "nextPage": null
}

I just want to the delete the password. How I can achieve this? The map I have done, still returns the password:

 usersAdmins.docs.map(async (u) => {
     delete u.password;
 });
1
  • JS map returns new array - the original array does not change. You need to store the result of the Map and return that. Commented Jan 14, 2021 at 9:17

4 Answers 4

1

I suspect the objects in your array are immutable, which is why your code didn't work.¹

Instead, create and return a new object, and use the array that map returns:

return {
    ...usersAdmins,
    docs: usersAdmins.docs.map(
        u => Object.fromEntries(Object.entries(u).filter(([key]) => key !== "password"))
    )
};

Live Example:

const usersAdmins = {
    "docs": [
        {
            "roles": [
                "Admin",
                "Read",
                "Modify",
            ],
            "_id": "5ffecc12a687a30580239a10",
            "name": "john",
            "email": "[email protected]",
            "password": "$2a$10$K6oKiiWKsIWmAGgkG7TmH.WjVpraNg45Uc0nber3FnF26oEzdgTS2",
            "created": "2021-01-13T10:31:46.982Z",
            "__v": 0
        },
        {
            "roles": [
                "Read"
            ],
            "_id": "5ffea1f1dd60b80718af6e3b",
            "name": "Megan",
            "email": "[email protected]",
            "password": "$2a$10$V8ARIjxhEHCC1COcvtQEmOZ3IfXm5oiANdLmyHyipy1GmWSD3ctWK",
            "created": "2021-01-13T07:32:01.665Z",
            "__v": 0
        },
    ],
    "totalDocs": 2,
    "limit": 10,
    "totalPages": 1,
    "page": 1,
    "pagingCounter": 1,
    "hasPrevPage": false,
    "hasNextPage": false,
    "prevPage": 1,
    "nextPage": null
};
const result = {
    ...usersAdmins,
    docs: usersAdmins.docs.map(
        u => Object.fromEntries(Object.entries(u).filter(([key]) => key !== "password"))
    )
};
console.log(result);


¹ Re your original code:

  1. The async is pointless, none of the code in your callback is using await (nor does it need to)
  2. using map but not using the array it creates is an anti-pattern. If you don't need the result array, use forEach or a for-of loop or just a for loop. (But here I suspect we do need to use the array that map produces.)
Sign up to request clarification or add additional context in comments.

Comments

1

If you are using Mongoose lib for model User, declare the password field like this would solve your problem.

const UserSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Please add a name']
    },
    email: {
        type: String,
        required: [true, 'Please add an email'],
        unique: true,
        match: [
            /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/,
            'Please add a valid email'
        ]
    },
    role: {
        type: String,
        enum: ['user', 'publisher'],
        default: 'user'
    },
    password: {
        type: String,
        required: [true, 'Please add a password'],
        minlength: 6,
        select: false // <=== IMPORTANT
    }
});

It means that password would not be returned whenever you get Users.

Comments

0

you can create a new object in map and return that, or set the password to the empty string with Object.assign

const data = [{
    "roles": [
      "Admin",
      "Read",
      "Modify",
    ],
    "_id": "5ffecc12a687a30580239a10",
    "name": "john",
    "email": "[email protected]",
    "password": "$2a$10$K6oKiiWKsIWmAGgkG7TmH.WjVpraNg45Uc0nber3FnF26oEzdgTS2",
    "created": "2021-01-13T10:31:46.982Z",
    "__v": 0
  },
  {
    "roles": [
      "Read"
    ],
    "_id": "5ffea1f1dd60b80718af6e3b",
    "name": "Megan",
    "email": "[email protected]",
    "password": "$2a$10$V8ARIjxhEHCC1COcvtQEmOZ3IfXm5oiANdLmyHyipy1GmWSD3ctWK",
    "created": "2021-01-13T07:32:01.665Z",
    "__v": 0
  },
];

const dataWithOutPassword = data.map((user) => {
  return {
    roles: user.roles,
    _id: user._id,
    name: user.name,
    email: user.email,
    created: user.created
  }
});

console.log(dataWithOutPassword);

const dataWithOutPassword2 = data.map((user) => {
  return Object.assign({}, user, {
    password: ''
  })
});

console.log(dataWithOutPassword2)

Comments

0

in paginate function you can select every fields that you need with select property, like following code:

await userAdminSchema.paginate({}, {
       select: "name email",
        sort: { created: 'desc' },
        limit: pagination.limit ? parseInt(pagination.limit) : 10,
        page: pagination.page ? parseInt(pagination.page) + 1 : 1,
      });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.