Is it better to bind a function to each object individually or create a helper object in Javascript/AngularJS?

Here's a quick question that I'm not sure how to search for online.

Imagine you have a JSON list of 'persons' from an API in AngularJS, and you convert it into a JavaScript array/object:

[
  {firstName: 'Foo', lastName: 'Bar'},
  {firstName: 'Banana', lastName: 'Fruit'}
]

You want a function that combines the first and last names into a full name.

Which approach is generally considered better - solution 1 or 2?

Solution 1: Each object in the array has its own method to create a full name.

[
  {firstName: 'Foo', lastName: 'Bar', fullName: function(){return this.firstName+' '+this.lastName;}},
  {firstName: 'Banana', lastName: 'Fruit', fullName: function(){return this.firstName+' '+this.lastName;}}
]

This seems like a very OOP approach, but is it the most efficient for Javascript (especially with long lists)?

Solution 2: Create a helper function that is instantiated just once.

var helper = function(person)
{
   return person.firstName+' '+person.lastName;
}

It may be simple, but sometimes getting the basics right is key ;)

Answer №1

Instead of adding a function to every single object in your first solution, which can be cumbersome especially with a large number of objects, consider a lighter approach as mentioned in the second solution.

Here's another suggestion:

You may want to consider parsing your JSON data into a specific object structure by referring to this resource:

Parse JSON String into a Particular Object Prototype in JavaScript

After defining the object prototype, you can use it like this:

Foo.prototype.fullname = function (){
    return this.firstName+' '+this.lastName;
}

This way, each Foo object can access the fullname() method through the prototype, resulting in better memory efficiency (only stored once in memory instead of in every object).

Answer №2

Boris Charpentier has provided a solid answer, and I'd like to supplement it with some example code:

Below is a constructor function that can initialize itself using a raw JSON object:

function Workout(workoutJson) {
    if (workoutJson) {
       this.duration = workoutJson.duration;
       ... // or copy all properties in a for-loop
    }
}

var fn = Workout.prototype;

// extending the prototype with additional functions
fn.getSomeData = function () {
   return this.onePart + ' ' + this.anotherPart;
};

// an alternative solution: defining properties (requires a modern browser)
Object.defineProperties(fn, {
   durationMinutes: {
      enumerable: true,
      get: function () {
         return roundMillisToMinutes(this.duration);
      },
      set: function (val) {
         this.duration = val * 60000;
      }
   }
});

By implementing a property durationMinutes, you create a real-like property that includes both getter and setter functions.

Let's include some static functions (no need for instances), which we can use later for converting raw JSON objects to domain objects:

Workout.fromJson = function(workoutJson) {
   return new Workout(workoutJson);
};

Workout.fromJsonArray = function(workoutJsonArray) {
   return workoutJsonArray.map(Workout.fromJson);
};

In my data access service, I convert raw data into instances of the domain model (Workout in this instance):

/**
 * Get a list overview of all workouts.
 * @returns {*} a promise resolving in an array of `Workout` objects
 */
function getOverview() {
   var defer = $q.defer();

   $http.get('/api/web/workouts?overview=1')
      .success(function (data) {
         defer.resolve(Workout.fromJsonArray(data));
      }).error(function (response) {
         defer.reject(response);
      });

   return defer.promise;
}

/**
 * Retrieve a single Workout using its `extId`.
 * @param extId
 * @returns {*} a promise resolving in the fetched workout
 */
function getByExtId(extId) {
   return WorkoutRS.get({id: extId}).$promise.then(function (data) {
      return $q.when(Workout.fromJson(data));
   });
}

Note: There may be better ways to handle $q promises, such as chaining instead of using $q directly. This approach showcases transforming raw JSON data into JavaScript "constructed" objects (featuring helper methods or properties in their prototype).

Edit

I came across an informative article on this topic in the Opinionated AngularJS blog.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A missing definition for req.body.object

The issue with the req.body.object variable persists. Even though I have body parser imported, the value remains undefined when I try to console.log() it. //javascript const express = require('express'); var bodyParser = require('body-pa ...

Using Vue.js to reset a timer with props

<template> <span>{{time}}</span> </template> <script> export default { name: 'Timer', data () { return { time: 0 } }, mounted () { setInterval(() => { ++this ...

What is the best way to incorporate correct reference logic when utilizing Joi validation?

I am currently working on designing a straightforward schema to validate inputted number ranges. The condition is that the start value should be less than the end value, and conversely, the end value must be greater than the start value. Below is the sche ...

Insufficient memory error - Garbage Collection overload exceeded

When converting a DOCX file to an HTML file using an XHTML converter in Java, there is an issue that arises before the conversion process. The error messages encountered are: String root = finalDestinationPath; int lastIndex = sDocPath.lastIndexOf(File. ...

Testing the API client against a remote API with constantly changing endpoints

Imagine I'm developing an API client for a complex API that is constantly changing and unreliable. I want to test this client using Jest, but I prefer to test it against a snapshot of the API response rather than the live API. However, I don't wa ...

Leveraging various techniques within a single controller in AngularJS

I am seeking assistance and advice on a coding issue I am facing. I am attempting to use two methods in one controller. The first method is to display selected rooms, while the second method is to display selected pax. However, only the first method seems ...

Is it possible to dynamically incorporate directives within an AngularJS application?

I'm attempting to utilize several custom directives within the Ionic framework. The dynamic structure is like <mydir-{{type}}, where {{type}} will be determined by services and scope variables, with possible values such as radio, checkbox, select, ...

The NextJS i18n feature is encountering an issue with the locale being undefined

Currently, I'm in the process of transitioning my website to NextJS, and I've run into some difficulties with internationalization. Even though I'm following the steps outlined in the official documentation, the locale displayed in the insp ...

Implementing file uploads using AJAX in CodeIgniter will continue to run, even if the value is null or undefined

I need to trigger another ajax request if the file has not been input yet. However, it is currently still carrying out the form action. Below is my view code: <form method="POST" id="quiz_file" action="<?php echo site_url('home/upload_quiz/&ap ...

How can an AngularJS/Ionic mobile application incorporate an external JavaScript script?

Can external JavaScript scripts be executed in an AngularJS/Ionic mobile app, particularly on non-jailbroken iOS devices? We are considering creating a launcher version of our app that downloads the required scripts and then installs and runs them. I have ...

Is it considered safe to modify variables by using this[varName] = something within a function that includes varName as a parameter?

As I continue working on this function, a question arises regarding the safety of changing variables in this manner. In my Angular service, I utilize utility functions where context represents this from the component calling the function. The code snippet ...

Tips for refining search outcomes from web scraping with Google App Script

My objective is to scrape data from the website : I am specifically interested in extracting the SP500 PE number, which currently stands at 39.57 (at the time of writing). I require this number to be formatted as 39,57, rather than 39.57. This is my curr ...

"Encountering issues with Ajax POST functionality - caught in a twist

Twisted.Web and AJAX I've encountered a similar thread where the issue of fetching data with AJAX from a Twisted server is discussed. Despite trying the code provided in that thread, I still face the same problem - the Twisted server works perfectly, ...

JavaScript OOP problem with object instances

I'm currently working on developing an app in JavaScript and trying to grasp the concept of Object-Oriented Programming. I created a simple "class" where I set an empty array in its prototype. However, when I create objects from this class and pass va ...

The watcher fails to function properly when attempting to pass data from a for loop in the parent component

<div v-for= "(item , index) in chartData" class="col" :key="index"> <ColumnChart :chartdata="item.tactical" :simpletype="true" /> </div> One of the properties I have is called chartData, initially set as an empty array. Upo ...

What's the best way to implement asynchronous state updating in React and Redux?

In my React incremental-style game, I have a setInterval function set up in App.ts: useEffect(() => { const loop = setInterval(() => { if (runStatus) { setTime(time + 1); } }, rate); return () => clearInterval(lo ...

What is the approach to initiating a jquery function once HTML content is dynamically added through an AJAX call?

<div id="timeline"> <ul class="grow" id="grown"><li>One</li><li>Two</li><li>Three</li><li>Four</li><li>Five</li><li>Six</li><li>Seven</li><li>Eight< ...

jQuery Slider Showing Incorrect Images

My jQuery slider is acting strangely. It hides the first image, shows the second one, but then just repeats the cycle by showing the first image again instead of loading the third one. I'm puzzled about what could be causing this issue in my code. Do ...

What is the best way to transfer a user-generated PNG file to my backend server?

I'm in the process of developing a website that enables users to generate personalized graphics and easily download them directly from the platform. My approach involves allowing users to customize an svg using a javascript-powered form, which is the ...

Is there a way to automatically populate an AngularJS input field?

Attempting to automate filling out a website using JavaScript. The script below: document.getElementsByClassName('form-control')[1].value = "MYNAME"; The input text changes, but upon clicking the submit button it displays as empty. Any as ...