TypeError: sentimentCurrent.map is not a function?

Trying to write a unit test for the below function.

I'm getting an error of

TypeError: sentimentCurrent.map is not a function

      65 |     console.log("sentimentData:",sentimentCurrent,typeof sentimentCurrent);
      66 | 
    > 67 |     sentimentCurrent.map(function (k, num) {
         |                      ^
      68 |       let dateCreated = new Date(k.created * 1000);
      69 | 
      70 |       DataInput.push({

The actual function is below, it takes in raw data and then prepares it to be used in a linegraph essentially.

    export default function generateLineGraphPointsSentiment(
  sentimentData
) {
  
  if (sentimentData !=null) {
  const DataInput = [];

  Object.keys(sentimentData).map(function (key, item) {
    var sentimentCurrent = sentimentData[key];
    sentimentCurrent.map(function (k, num) {
      let dateCreated = new Date(k.created * 1000);

      DataInput.push({
        created: dateCreated,
        sentiment: k.sentiment,
        magnitude: k.magnitude,
        date: k.createdDay,
      });
    });

    // {created: 1601820360, sentiment: -0.1, magnitude: 0.1, createdDay: "2020-10-05"}
  });

  

  return DataInput
}
else { return 0 }
}

The test case is as follows,

import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import generateLineGraphPointsSentiment from './generateGraphPointsAnalysis';

    const ExpressionData = [
  {
    "2021-08-21": [
        {
            "id": 96451,
            "user_id": "xxxx",
            "sentiment": 0.4,
            "magnitude": 1,
            "created": 1629535058,
            "createdDay": "2021-08-21"
        },
        {
            "id": 96452,
            "user_id": "xxx",
            "sentiment": -0.1,
            "magnitude": 1,
            "created": 1629535060,
            "createdDay": "2021-08-21"
        },
        
    ]
}

// const setSelectedDate = jest.fn();

describe('Generates Graph Points Sentiment', () => {
  it('should show loader for the LineGraphs graph if no data is present', () => {
    generateSentimentLineGraph = generateLineGraphPointsSentiment(SentimentData);
    console.log(generateSentimentLineGraph,SentimentData,typeof SentimentData);

    expect(generateSentimentLineGraph).toHaveReturned();
  });
});

Any ideas on what is wrong with my code? It works in dev currently, not sure why it's failing this test now? I think it has something to do with either the type of data being processed, or how I'm using the map functions. Perhaps I can simplify the first map function?

Updated test data to duplicate what is going in at start, and the after the first map data is like this,

[
    {
        "id": 96451,
        "user_id": "xxx",
        "sentiment": 0.4,
        "magnitude": 1,
        "created": 1629535058,
        "createdDay": "2021-08-21"
    },
    {
        "id": 96452,
        "user_id": "xxx",
        "sentiment": -0.1,
        "magnitude": 1,
        "created": 1629535060,
        "createdDay": "2021-08-21"
    },
]

Keeping in mind this currently works when used in the line graph, which is like this from ReCharts library,

<LineChart
        width={550}
        height={250}
        data={Sentiment}
        syncId="anyId"
        margin={{
          top: 10,
          right: 30,
          left: 0,
          bottom: 0,
        }}
      >

Great answers, works for the test now, but in loading in the dev environment I get this error weirdly,

enter image description here


If functionality works fine - I assume that the problem is with your const SentimentData.

Because from the looks of it, Object.keys(sentimentData) expects sentimentData to be a "proper" object, like {key: "bla"}. Instead, you're giving it an array, which technically still is an object, so for an array of two elements, you'll get two keys: ["0", "1"].

And then you do sentimentCurrent = sentimentData[key]; which is same as sentimentCurrent = sentimentData["0"]; which just retuns first, or second object from the array.

And then you're trying to run Array.map() function on an object which doesn't make sense.

So, my advice, if functionality works as expected, try logging your sentimentData and update mocked data in the test accordingly.

This should work:

function generateLineGraphPointsSentiment(sentimentData) {
  if (sentimentData != null) {
    const DataInput = [];

    Object.keys(sentimentData).map(function (key, item) {
      var sentimentCurrent = sentimentData[key];

      sentimentCurrent.map(function (k, num) {
        let dateCreated = new Date(k.created * 1000);

        DataInput.push({
          created: dateCreated,
          sentiment: k.sentiment,
          magnitude: k.magnitude,
          date: k.createdDay,
        });
      });

      // {created: 1601820360, sentiment: -0.1, magnitude: 0.1, createdDay: "2020-10-05"}
    });

    return DataInput;
  }
}

const SentimentData = {
  "2021-08-21": [
    {
      id: 96451,
      user_id: "xxxx",
      sentiment: 0.4,
      magnitude: 1,
      created: 1629535058,
      createdDay: "2021-08-21",
    },
    {
      id: 96452,
      user_id: "xxx",
      sentiment: -0.1,
      magnitude: 1,
      created: 1629535060,
      createdDay: "2021-08-21",
    },
  ],
};

const generateSentimentLineGraph = generateLineGraphPointsSentiment(SentimentData);

console.log(generateSentimentLineGraph);

The parameter that you pass in the test case. you should use ExpressionData replace SentimentData. you should modify your code like this, 'generateLineGraphPointsSentiment(ExpressionData);'


sentimentCurrent is an object... one of the elements from the SentimentData array. I don't see a map property on it that is a function, so the error tracks.

From what I can see it looks like you are trying to map the passed sentimentData array into DataInput where you've augmented/updated the created property.

const SentimentData = [
  {
    id: 96452,
    user_id: 'asdasd',
    sentiment: -0.1,
    magnitude: 1,
    created: 1629535060,
    createdDay: '2021-08-21',
  },
  {
    id: 96453,
    user_id: 'asdasd',
    sentiment: 1,
    magnitude: 1,
    created: 1629535063,
    createdDay: '2021-08-21',
  },
];

...

export default function generateLineGraphPointsSentiment(sentimentData) {
  console.log("sentimentData:", sentimentData, typeof sentimentData);
  if (sentimentData !=null) {
    const DataInput = sentimentData.map(item => {
      const dateCreated = new Date(item.created * 1000);

      return {
        created: dateCreated,
        sentiment: item.sentiment,
        magnitude: item.magnitude,
        date: item.createdDay,
      }
    });

    // {created: 1601820360, sentiment: -0.1, magnitude: 0.1, createdDay: "2020-10-05"}

  ...

Update

You seem to have changed the data that is supposedly sent to generateLineGraphPointsSentiment. This is an array of objects with a single key and array of objects.

const ExpressionData = [
  {
    "2021-08-21": [
      {
        id: 96451,
        user_id: "xxxx",
        sentiment: 0.4,
        magnitude: 1,
        created: 1629535058,
        createdDay: "2021-08-21"
      },
      {
        id: 96452,
        user_id: "xxx",
        sentiment: -0.1,
        magnitude: 1,
        created: 1629535060,
        createdDay: "2021-08-21"
      }
    ]
  }
];

Map over the outer array, then map over the inner object values array to map these elements to the DataInput element objects you want. Flatten all the arrays down.

export default function generateLineGraphPointsSentiment(sentimentData) {
  console.log("sentimentData:", sentimentData, typeof sentimentData);
  if (sentimentData !=null) {
    const DataInput = sentimentData.flatMap((el) => {
      return Object.values(el).flatMap((values) => {
        return values.map((item) => {
          const dateCreated = new Date(item.created * 1000);

          return {
            created: dateCreated,
            sentiment: item.sentiment,
            magnitude: item.magnitude,
            date: item.createdDay
          };
        });
      });
    });

    // {created: 1601820360, sentiment: -0.1, magnitude: 0.1, createdDay: "2020-10-05"}

  ...

const ExpressionData = [
  {
    "2021-08-21": [
      {
        id: 96451,
        user_id: "xxxx",
        sentiment: 0.4,
        magnitude: 1,
        created: 1629535058,
        createdDay: "2021-08-21"
      },
      {
        id: 96452,
        user_id: "xxx",
        sentiment: -0.1,
        magnitude: 1,
        created: 1629535060,
        createdDay: "2021-08-21"
      }
    ]
  }
];

const DataInput = ExpressionData.flatMap((el) => {
  return Object.values(el).flatMap((values) => {
    return values.map((item) => {
      const dateCreated = new Date(item.created * 1000);

      return {
        created: dateCreated,
        sentiment: item.sentiment,
        magnitude: item.magnitude,
        date: item.createdDay
      };
    });
  });
});

console.log(DataInput);