2

I'm having a following situation where I want to know the indexOf value to be able to use that knowledge later on in the code. How ever, I've tried multiple different ways to get the value and I don't seem to get it right. In the code below I've tried a few different ways that I found searching Stackoverflow. All of them return -1 so far, meaning that there is either something wrong with my code or some other issue I'm not able to find at the moment.

FYI, selectedGroup is an array with objects inside, just like this: [{label: "somelabel", value: 100}] and there can be many of them, depends on the user.

code:

import React, { useState, useEffect } from 'react';

const GroupButtonMaker = ({ selectedGroup}) => {
  const [newButtons, setNewButtons] = useState([]);
  console.log(newButtons);

  useEffect(() => {
    const createButtons = () => {
      setNewButtons(
        selectedGroup.map(item => {
          return (
            <button
              id={item.value}
              className={'btn green micro'}
              key={item.value}
              onClick={event => btnHandler(event)}
            >
              {item.label}
            </button>
          );
        })
      );
    };
    createButtons();
  }, [selectedGroup]);

  const btnHandler = event => {
//here at the handler I'm trying multiple different ways to find indexOf as a test. No luck so far. 
    const eventID = event.currentTarget.id;
    let currentTargetIndex = newButtons
      .map(item => item.value)
      .indexOf(eventID);
    console.log(currentTargetIndex);
    console.log(newButtons.findIndex(x => x.value === eventID));
  };

  Array.prototype.indexOfObject = function arrayObjectIndexOf(property, value) {
    for (var i = 0, len = this.length; i < len; i++) {
      if (this[i][property] === value) return i;
    }
    return -1;
  };
// here i've hardcored one value as a test to see if it works but it didn't so far.
  console.log(newButtons.indexOfObject('value', 107));

  const idx = newButtons.reduce(function(cur, val, index, eventID) {
    if (val.value === eventID && cur === -1) {
      return index;
    }
    return cur;
  }, -1);
  console.log(idx);

  return <ul>{newButtons.map(item => item)}</ul>;
};
export default GroupButtonMaker;

Thank you beforehand for any suggestions to my current problem. Hopefully I've managed to describe the problem in a way that makes it solveable. If not, please ask and I'll try to provide an answer.

1
  • At newButtons.map(item => item.value), each item is a <button>, map with .value will return an array of undefined. You couldn't find eventID in an array of undefined, that's why it returned -1 Commented Dec 27, 2019 at 15:15

1 Answer 1

1

Why not simply pass the id of the button to the handler instead of getting it from event.

You can achieve it by this: onClick={(event) => btnHandler(item.value)}

And then in your btnHandler, just look up the index of the selected button from selectedGroup instead of newButtons.

Here, give this a try:

import React, { useState, useEffect } from "react";

const GroupButtonMaker = ({ selectedGroup }) => {
  const [newButtons, setNewButtons] = useState([]);

  useEffect(() => {
    const buttons = selectedGroup.map(item => {
      return (
        <button
          id={item.value}
          className={"btn green micro"}
          key={item.value}
          onClick={(event) => btnHandler(item.value)}
        >
          {item.label}
        </button>
      );
    });
    setNewButtons(buttons);
  }, [selectedGroup]);

  const btnHandler = buttonId => {
    const selectedButtonIndex = selectedGroup.findIndex(item => item.value === buttonId);
    console.log("selectedButtonIndex is: ", selectedButtonIndex);
  };
  return <ul>{newButtons.map(item => item)}</ul>;
};
export default GroupButtonMaker;

Here's a Working Sample Code Demo for your ref.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. You're indeed right, it works and fits for my purpose. I'll mark this as the right answer!

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.