0

I'm working on a React/Redux application. I receive a data object from the api resembling this:

const dataObj = [
  {
    id: 1,
    name: "Filo",
    activity: 9,
    info: {
      statusCode: 4
    }
  },
  {
    id: 2,
    name: "Spot",
    activity: 8,
    info: {
      statusCode: 2
   }
 }
];

I have to run the data through a series of conditional function to create dom elements at different points like this:

const getElementsIcons = dog => {
    const elementData = []

    elementData.push({...})

    if (dog.info.statusCode === ADOPTED_ID) {
        elementData.push({...})
    }
    if (dog.info.statusCode === PENDINGID) {
        elementData.push({...})
    }
    if (dog.info.statusCode === PENDING_ID && dog.activity === OTHER_VALUE) {
        elementData.push({...})
    }

    return elementData
}

However, does it make sense to have this conditional logic inline above, or should I create a 'class' like so:

function Dog(data) {
  this.name = data.name;
  this.isAdopted = data.statusCode === ADOPTED_ID;
  this.otherCondition =
    data.statusCode === PENDING_ID && data.activity === OTHER_VALUE;
}

Then deal with the modified data throughout the application?

If it makes sense to create a class, should I do this when I normalize the data from the api call where I store it in redux, or later on when I pass it to the react component that consumes the data?

2 Answers 2

1

If javascript were a pure object oriented programming language, I would have recommended to you to create an object to encapsulate data with behavior, since it's the very purpose of OOP. By doing that, you keep isolated the mutations applied to your objects.

But, javascript is also a functionnal programming language. In functionnal programming language, we do the opposite, we separate data from behaviors to favor functions composition. But to avoid the pitfalls of an Anemic Domain Model, you should ensure the immutability of your objects, to avoid accidental mutations.

All in all, I would not recommend you to create a specific class as an encapsulation mechanism but use a module instead, something like this :

// in /some/path/dog.js

const Dog = (theDogData) => {
  const isAdopted = data.statusCode === ADOPTED_ID;
  const otherCondition = data.statusCode === PENDING_ID && data.activity === OTHER_VALUE;
  return Object.freeze({
    isAdopted,
    otherCondition,
  });
}

module.exports = {
  Dog,
};

Using module instead of Class let you just require individual method without being tied to a real object. So if you want your Dog to be able to do some thing that many Animals can do (like eating), you can require this function from the Animal module. By doing so, if later on you need an animal that for whatever reason you don't need it to be able to "eat", you don't have to require this method. This protects you from the Gorilla / Banana problem and the Fragile Base Class problem. I can only suggest you to learn more about that in the excellent post Composition over inheritance from Mattias Petter Johansson. It's very well explained !

3
  • This approach feels more familiar to me. Would you mind expanding on why you would use a module instead? Would you still recommend this approach if it was expanded to a parent class, lets say Animals, Dog and Cat being sub classes?
    – mtmoran
    Commented Dec 17, 2018 at 15:09
  • 1
    Sure ! I've edited my answer, with a link that exposes this very example (with animals, cat, dog, etc.) Commented Dec 17, 2018 at 15:26
  • Great resources. Thanks, that makes me rethink how I go about everything. I appreciate your response.
    – mtmoran
    Commented Dec 17, 2018 at 15:50
0

Generally, given two or more things that work together think about making an object to encapsulate that interaction. I think that's the case here - dataObj objects yield Dog objects which are used to create elementData (DOM elements).


should I do this when I normalize the data from the api call where I store it in redux, or later on when I pass it to the react component that consumes the data?

Generally raw data is best converted up front into "problem domain context" object(s). Thus your application code is totally unaware of the raw data per se.

That data conversion should ideally be an object, and depending on the complexity of that conversion, uses one or more other objects (such as Dog).


You are creating Dog objects to hold all of a given dog's information as derived from the raw dataObj. So calculate "what DOM element" there too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.