Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sub methods in Javascript classes

The problem

I'd like to be able to use classes to create client objects and add address objects to an array within them.

What I'd like to be able to do

let client = new Client ('A123', 'John', 'Smith', avatarUrl);
client.address('home').add(address);

My current classes

Working version

class Client extends Name {
  constructor(clientRef, firstName, lastName, profilePic) {
    super (firstName, lastName, profilePic);
    this._id = clientRef;
    this.addresses = [];
  }
  addAddress (address, label = 'main') {
    address = {...address, label}
    this.addresses.push(address);
  }
  removeAddress (label = 'main') {
    this.addresses = this.addresses.filter((element) => { return element.label != label; });
  }
}

Non-working version

This is what I'm trying to create, but it doesn't work.

class Client extends Name {
  constructor(clientRef, firstName, lastName, profilePic) {
    super (firstName, lastName, profilePic);
    this._id = clientRef;
    this.addresses = [];
  }
  address (label = 'main') {
    add (address) {
      address = {...address, label}
      this.addresses.push(address);
    }
    remove () {
      this.addresses = this.addresses.filter((element) => { return element.label != label; });
    }
  }
}
like image 877
Jason Berryman Avatar asked Mar 27 '26 07:03

Jason Berryman


2 Answers

You're trying to assign values to a class method as if it were a key-value object store. It's a function that will return a null reference without a return statement. What you need to do it return a key-value store that has the methods you want, like this:

class Client extends Name {
  constructor(clientRef, firstName, lastName, profilePic) {
    super (firstName, lastName, profilePic);
    this._id = clientRef;
    this.addresses = [];
  }
  address (label = 'main') {
    return {
      add: (address) => {
        address = {...address, label}
        this.addresses.push(address);
      },
      remove: () => {
        this.addresses = this.addresses.filter((element) => { return element.label != label; });
      }
    }
  }
}
like image 78
Jacob Penney Avatar answered Mar 29 '26 20:03

Jacob Penney


What you can do is to return an object holding these functions, but you need to ensure that this points to the original Client object, and for that, you could utilize arrow functions:

class Client extends Name {
  constructor(clientRef, firstName, lastName, profilePic) {
    super(firstName, lastName, profilePic);
    this._id = clientRef;
    this.addresses = [];
  }
  address(label = 'main') {
    return {
      add: (address) => {
        address = {
          ...address,
          label
        }
        this.addresses.push(address);
      },
      return: () => {
        this.addresses = this.addresses.filter((element) => {
          return element.label != label;
        });
      }
    }
  }
}
like image 35
t.niese Avatar answered Mar 29 '26 22:03

t.niese



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!