Home > OS >  filtering object of array by id - REACT
filtering object of array by id - REACT

Time:03-19

I'm having a big struggle with filtering an object of an array of objects by its ID in React. Let me explain:

The App is a Notes app, that stores every note you create with its Title, Text(name) and created date. The key is the ID.

Now I'm trying to create a popup modal every time I click on a note, which I managed to do ok, except for one thing: when the modal appears, it doesn't show only the selected note but all the notes list. I've tried with different array methods to filter the note I need, but didn't succeed.

This is the App.js file:

import React, { useState } from 'react';
import './App.css';
import Form from './components/Form';
import List from './components/List';
import { v4 as uuidv4 } from 'uuid';
import Modal from 'react-modal';
import ModalList from './components/ModalList';


Modal.setAppElement('#root');

function App() {
  /*HOOKS */

  const [list, setList] = useState([]);
  const [modalList, setModalList] = useState([]);


  //for modal:
  let subtitle;
  const [modalIsOpen, setIsOpen] = React.useState(false);




  /*FUNCTIONS */

  //add new notes
  function handleAdd(title, name) {
    if (name) {
      const newList = list.concat({ title: title, name: name, id: uuidv4(), date: getCurrentDate() });
      setList(newList);
      console.log(newList);
      const newModalList = list.concat({ title: title, name: name, id: uuidv4(), date: getCurrentDate() });
      setModalList(newModalList);
    }
    else { alert("You should complete the notes field") }

  }


  //get the date for adding the note
  function getCurrentDate() {

    let newDate = new Date()
    let date = newDate.getDate();
    let month = newDate.getMonth()   1;
    let year = newDate.getFullYear();
    let hours = newDate.getHours();
    let minutes = newDate.getMinutes();

    return `${month < 10 ? `0${month}` : `${month}`}/${date}/${year}, ${hours}:${minutes < 10 ? `0${minutes}` : `${minutes}`} hs.`

  }


  //deleting a note
  function del(x) {
    if (window.confirm("Do you really want to delete this item? The action is permanent.")) {
      const newList = list.filter((item) => item.id !== x);
      setList(newList);
    }
  }



  //opening a modal
  function openModal() {

    setIsOpen(true);
  }

  //after opening a modal
  function afterOpenModal() {
    // references are now sync'd and can be accessed.
    subtitle.style.color = '#f00';

  }

  //closing a modal
  function closeModal() {
    setIsOpen(false);

  }


  /*APP */
  return (
    <>

      <div>
        {/* MODAL */}
        <Modal
          isOpen={modalIsOpen}
          onAfterOpen={afterOpenModal}
          onRequestClose={closeModal}
          style={customStyles}
          contentLabel="Example Modal"
        >
          {modalList.map((item) => { return <ModalList key={item.id} item={item} quit={closeModal} /> })}
        </Modal>
      </div>

      {/* FORM */}


      <div className='App'>
        <Form handleNew={handleAdd} />
      </div>

      {/* NOTES LIST */}
      <div className='notes-list'>
        {list.map((item) => { return <List key={item.id} item={item} quit={del} addModal={openModal} /> })}
      </div>

    </>
  );
}

export default App;



And this is the ModalList.jsx file:

const ModalList = (props) => {
    const { item, quit} = props;

    /*LIST */
    return (
        <li ><button className='delete' onClick={()=>quit(item.id)}>x</button><p className='note-title'>{item.title}</p><p>{item.date}</p><p className='note-name'>{item.name}</p> </li>


    );
}
 
export default ModalList;

I know I have to someway filter the object by its ID so that only appears what I clicked and not all the existing elements in the list, but I'm not finding the way.

Thanks a lot!

CodePudding user response:

You are using Array.map here which is doing what it's supposed to do (listing the items), instead you should be using Array.filter which would return the ModalItem you need

CodePudding user response:

{list.map((item) => { return <List key={item.id} item={item} quit={del} addModal={openModal} /> })}

openModal needs pass the item you clicked as a parameter and pass it to the callback.

Something like:

{list.map((item) => { return <List key={item.id} item={item} quit={del} addModal={() => openModal(item)} /> })}

Then openModal function needs to pass that parameter to the Modal component. To achieve that you can store it in your modalList for instance via setModalList([item])

  • Related