Add built-in function omit keys from an object

add a built-in function called Omit. What it does is return the object back BUT removes specified keys,

So if you have:

Get(
  Match(
    Index("userByEmail"),
    "user@email.com"
  )
)

Which returned:

{
  // ... other meta values
  data: {
    email: "user@email.com",
    name: "Juan Dela Cruz",
    hashedPassword: "asdasd12312radgadgvadfasfr12esa" // pretend it's a hashed string :)
  }
}

Applying the omit function like so:

Omit(
  ["hashedPassword"],
  Select(
    ["data"],
    Get(
      Match(
        Index("userByEmail"),
        "user@email.com"
      )
    )
  )
);

Should return

{
  email: "user@email.com",
  name: "Juan Dela Cruz"
}

furthermore, the first argument can accept a 2d array, like so:

Omit(
  [
    ["data", "hashedPassword"] // remove the data.hashedPassword from the object
  ],
  Get(
    Match(
      Index("userByEmail"),
      "user@email.com"
    )
  )
);

Resulting to the following:

{
  // ... other meta values
  data: {
    email: "user@email.com",
    name: "Juan Dela Cruz"
  }
}

So to summarize, the function would be:

Omit(paths, fromObject)

  • Paths: Array of paths to the keys to be omitted.
  • fromObject: Target object to derive the result from.

Omit must be a pure function, that is, it doesn’t mutate the fromObject parameter, so you can do:

Let(
  {
    result: Select(
      ["data"],
      Get(
        Match(
          Index("userByEmail"),
          "user@email.com"
        )
      )
    ),
    removedResult: Omit(
      [
        ["data", "hashedPassword"] // remove the data.hashedPassword from the object
      ],
      Var("result")
    )
  },
  // rest of the code
)

and Var("result") should still be the original object prior to Omit call.

Current work around that I found:

Unsure if there’s a better approach than this

Let(
  {
    result: Get(Match(Index("userByEmail"), "user@email.com")),
    filteredData: Merge(
      Select(["data"], Var("result")),
      {
        hashedPassword: null // this removes the hashedPassword from the result
      }
    )
  },
  Merge(
    Var("result"),
    {
      data: Var("filteredData")
    }
  )
)

which will return the same result as:

Omit(
  [
    ["data", "hashedPassword"]
  ],
  Get(Match(Index("userByEmail"), "user@email.com"))
)

Which will be this (from the example given above):

{
  // ... other meta values
  data: {
    email: "user@email.com",
    name: "Juan Dela Cruz"
  }
}

Hi @aprilmintacpineda,

You can also try this way.
If you have a document which looks like this:

Create(Collection('test'),{data:{val1:1,val2:2,val3:3,val4:4,val5:5,val6:6,val7:7,val8:8,val9:9,val10:10}})
{ ref: Ref(Collection("test"), "283968229559239173"),
  ts: 1607072057266000,
  data:
   { val1: 1,
     val2: 2,
     val3: 3,
     val4: 4,
     val5: 5,
     val6: 6,
     val7: 7,
     val8: 8,
     val9: 9,
     val10: 10 } }

and you want to omit some fields, you can do this way:

Let(
  {
    fieldsToOmit: ["val4","val5","val6","val9"],
    doc: Select(['data'],Get(Ref(Collection("test"), "283968229559239173"))),
    cleanedDoc: Reduce(Lambda(['acc','value'],Merge(Var('acc'),ToObject([[Var('value'),null]]))), Var('doc'),Var('fieldsToOmit'))
  },
  Var('cleanedDoc')
)

of course, you can replace the doc value with something more generic or even write a function and reuse the code.

In the meantime, I will file an FR for that function.

Luigi

2 Likes