TransWikia.com

Vue watch method not filtering object

Stack Overflow Asked on December 5, 2021

The filter option does not seem to be working in a Vue watched function. The below should remove the E: object, but it does not remove anything. I have confirmed the filter code is executing, returning false for the E: object, and true for everything else (expected). However, the item remains in the array.

The object passed to the component via prop:

[
    {
        "fs": "C:",
        "type": "NTFS",
        "size": 273649844224,
        "used": 265129050112,
        "use": 96.88624192856284,
        "mount": "C:"
    },
    {
        "fs": "D:",
        "type": "NTFS",
        "size": 1000202039296,
        "used": 879919800320,
        "use": 87.97420578539696,
        "mount": "D:"
    },
    {
        "fs": "E:",
        "type": "NTFS",
        "size": 524283904,
        "used": 35745792,
        "use": 6.818022015796998,
        "mount": "E:"
    },
    {
        "fs": "F:",
        "type": "NTFS",
        "size": 250058108928,
        "used": 193818132480,
        "use": 77.50923707729336,
        "mount": "F:"
    },
    {
        "fs": "G:",
        "type": "NTFS",
        "size": 249464614912,
        "used": 149687517184,
        "use": 60.00350680468374,
        "mount": "G:"
    }
]

Component Script:

export default {
  name: "DISK",
  props: ["diskinfo"],
  watch: {
    diskinfo: function () {
      if (typeof this.diskinfo !== "undefined") {
        // convert to GB
        this.diskinfo.forEach((disk) => {
          disk.used = (disk.used / 1073741824).toFixed(0);
          disk.size = (disk.size / 1073741824).toFixed(0);
        });
        // remove if < 1 gb
        this.diskinfo.filter((disk) => disk.size === "0"); //??? Not filtering
      }
    },
  },
};

3 Answers

As Phill and Cyrbuzz said, the filter function returns the filtered array so you have to change this:

this.diskinfo.filter((disk) => disk.size === "0");

To this:

this.diskinfo = this.diskinfo.filter((disk) => disk.size === "0");

Answered by Marques on December 5, 2021

  1. You should not be modifying a prop value. This is a Vue anti-pattern
  2. Array.prototype.filter() is about deciding what stays, not what goes so if you want to remove elements with size === 0, you should use a size > 0 comparison
  3. You aren't doing anything with the return value of Array.prototype.filter() so of course no changes will be persisted

I don't know what you're doing with the diskinfo prop in this component but the typical way to handle something like this is with a computed property

export default {
  name: "DISK",
  props: { diskinfo: Array },
  computed: {
    formattedDiskInfo () {
      return this.diskinfo.map(di => ({
        ...di,
        used: (di.used / 1073741824).toFixed(0),
        size: (di.size / 1073741824).toFixed(0)
      })).filter(({ size }) => size > 0)
    }
  }
}

In your template, you would use the formattedDiskInfo array instead of the diskinfo prop.

Answered by Phil on December 5, 2021

Filter return a new one:

a = [1,2,3]

a.filter((b) => b < 2) // return [1] but a is still [1,2,3]

So you can do this:

this.diskinfo = this.diskinfo.filter((disk) => disk.size === "0")

Answered by Cyrbuzz on December 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP