James Mulholland
James Mulholland

Reputation: 1872

Is there an elegant way of passing an object of parameters into a function?

I have the following method which takes a set of data and creates a new instance of a model from it. The reportTemplateData comes in as an object which I destructure in order to pass in as a list of properties to the class constructor.

Whilst this works, I feel like it could be done far more efficiently. Is there a more elegant way to do this in a line or so?

addReportTemplate(reportTemplateData) {
  const {
    id,
    pageId,
    profileTemplateId,
    userId,
    name,
    description,
    createdAt,
    updatedAt,
    deletedAt,
    createdBy,
    updatedBy,
    deletedBy,
    reportTemplateColumns,
  } = reportTemplateData;
  const newReportTemplate = new ReportTemplate(
    id,
    pageId,
    profileTemplateId,
    userId,
    name,
    description,
    createdAt,
    updatedAt,
    deletedAt,
    createdBy,
    updatedBy,
    deletedBy,
    reportTemplateColumns,
  );
  this.reportTemplates.push(reportTemplates);
}

EDIT

Worth noting that if you go for the const newReportTemplate = new ReportTemplate({...reportTemplateData}) solution, you must match your data properties precisely to your class constructor parameters. This was an issue for me where the data was coming in in snake_case whereas my Javascript model was looking for camelCase.

Upvotes: 3

Views: 82

Answers (5)

xab
xab

Reputation: 1236

Assuming that only the properties you want to pass are in that object.

addReportTemplate(reportTemplateData) {
  const newReportTemplate = new ReportTemplate({ ...reportTemplateData });
  this.reportTemplates.push(reportTemplates);
}

If there are a few properties you want to exclude, destructure them.

addReportTemplate(reportTemplateData) {
  const { 
      excluded1,
      excluded2,
      ...properties,
   } = reportTemplateData;
  const newReportTemplate = new ReportTemplate({ ...properties });
  this.reportTemplates.push(reportTemplates);
}

Both of these approaches require a change in ReportTemplate class where the constructor takes an object as parameter. See two examples of how this approach would work in this pen.

Upvotes: 3

Finesse
Finesse

Reputation: 10801

If ReportTemplate must be given only specific parameters and addReportTemplate can be given any parameter, you can use this variant:

addReportTemplate(reportTemplateData) {
  const newReportTemplates = {};

  for (const param in [
    'id',
    'pageId',
    'profileTemplateId',
    'userId',
    'name',
    'description',
    'createdAt',
    'updatedAt',
    'deletedAt',
    'createdBy',
    'updatedBy',
    'deletedBy',
    'reportTemplateColumns',
  ]) {
    newReportTemplates[param] = reportTemplateData[param];
  }

  this.reportTemplates.push(newReportTemplates);
}

Otherwise the other answers are great.

Upvotes: 0

pritam
pritam

Reputation: 2558

Instead of destructuring reportTemplateData and passing individual fields from it, you could simply use spread operator ... and pass as object:

addReportTemplate(reportTemplateData) {
    const newReportTemplate = new ReportTemplate({...reportTemplateData});
    this.reportTemplates.push(newReportTemplate);
}

And finally in ReportTemplate receive the params as a single object and in there you could destructure required fields.

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370779

Use an array of property names instead, extract the properties from the argument, and call ReportTemplate with an object with those properties. You can use reduce to transform the array of property names into an object with those properties. For example:

function addReportTemplate(reportTemplateData) {
  const propNames = ['id', 'pageId', 'userId'];
  const templateArg = propNames.reduce((a, propName) => {
    a[propName] = reportTemplateData[propName];
    return a;
  }, {});
  console.log(templateArg);
}
addReportTemplate({
  id: 'id!',
  pageId: 'pageId!',
  userId: 'userId!',
  someOtherProp: 'someOtherProp'
});

Upvotes: 1

hsz
hsz

Reputation: 152216

First of all, your ReportTemplate can take a single object as an input parameter instead of having a plenty of arguments.

If it's not possible, you can simplify it a bit, having destructurization right in your function definition:

addReportTemplate({
    id,
    pageId,
    profileTemplateId,
    userId,
    name,
    description,
    createdAt,
    updatedAt,
    deletedAt,
    createdBy,
    updatedBy,
    deletedBy,
    reportTemplateColumns,
  }) {
    // ...
  }

Upvotes: 1

Related Questions