Search code examples
javascriptreactjsfunctionmapping

.map function in react is bringing a error


I am writing this code in which i have to map an array in some divs...

there is first code which has the mapping and the ui

import { useContext } from "react";
import "./index.scss";
import { PlaygroundContext } from "../../../Providers/PlaygroundProvider";
// import { logo } from "./logo.png"
// import { vlogo } from "./vlogo.png";


const Folder = ({folderTitle, cards}) =>{
      <div className="folder-container">
                 <div className="folder-header">
                    <div className="folder-header-item">
                    <span class="material-symbols-outlined" style={{color: "yellow"}}>{{folderTitle}}</span>
                    <span>{"Folder 1"}</span>
                     </div>
                    <div className="folder-header-item">
                    <span class="material-symbols-outlined">delete</span>
                    <span class="material-symbols-outlined">edit</span>
                    <button>
                    <span class="material-symbols-outlined">add</span>
                    <span>New File</span>
                    </button>
                    </div>
                </div>
                <div className="cards-container">
                {
                  cards?.map((file, index) => {
                    return(  <div className="card" key={index}>
                      {/* Logo=> <span class="material-symbols-outlined">article</span> */}
                      <img src={require('./vlogo.png')} />
                        <div className="title-container">
                            <span>{file?.title}</span>
                            <span>Language: {file?.language} </span>
                         </div>
                        <div style={{display: 'flex', gap: '10px'}}>
                        <span class="material-symbols-outlined">delete</span>
                        <span class="material-symbols-outlined">edit</span>
                        </div>
                      
                    </div>)
                  })
                }
            </div>
          </div>
} 

export const RightComponent = () => {
  
  const folders = useContext(PlaygroundContext);
  console.log(folders); 


    return(
        <div className="right-container">
            <div className="header">
                Code Projects
                <button className="add-folder">
                <span class="material-symbols-outlined">add</span>
                    <span>New Folder</span>
                </button>
            </div>
            {
                  folders?.map((folder, index) => {
                    return<Folder folderTitle={folder.title} key={index} cards={folders.files}/>;
                  })  
            }
        

        </div>
    );
}

and here is the container

import { createContext, useContext, useEffect, useState } from "react";
import {v4} from 'uuid';

export const PlaygroundContext = createContext();

const initialData = [
    {
        id:v4(),
        title: 'DSA',
        files: [
            {
                title: 'codewala',
                id:v4(),
                language: 'cpp',
                code:':Ldkidm'
            },
            {
                title: 'codewala2',
                id:v4(),
                language: 'cpp',
                code:':Ldkidmccccccc'
            }
            
        ]

    }
]

export const PlaygroundProvider = ({children}) =>{
    const [folders, setFolders] = useState(initialData);


    useEffect(() => {
        localStorage.setItem('data', JSON.stringify(folders))
    },[])
    const uniqId = v4();
    // console.log(uniqId);
    const obj = {name: 'divyansh'};
    return( 
//  <>{children}</>
    <PlaygroundContext.Provider value={{folders}}> 
    {children}
</PlaygroundContext.Provider>
    );
};

I dont why but the mapping is showing error

the error is

folders.map is not a function
TypeError: folders.map is not a function
    at RightComponent (http://localhost:3000/static/js/bundle.js:428:78)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:24807:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:28778:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:30081:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:15063:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:15107:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:15164:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:35062:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:34310:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:34233:9)

I tried stringfying the JSON Data but isnt helping I also saw other questions of stackoverflow but they arent helping


Solution

  • There are a few problems here that I'll go over, and then supply a "working" example of data at the end.

    1. {{folderTitle}} should just be {folderTitle}.
    2. class should always be className.
    3. In your component call you're using cards={folders.files} when it should be cards={folder.files} ("folder" singular, as you're picking up the folder variable from the callback)
    4. Your Provider value should be value={folders}.
    5. I've swapped out the map index in favour of using your object ids instead (see the pitfall section here on why).
    6. Multiple child elements need to be wrapped in a parent element - this is why there's an extra section element in the Folder component.

    const { useState, useContext, createContext } = React;
    
    const initialData = [
      {
        id:1,
        title: 'DSA',
        files: [
          {
            title: 'codewala',
            id:2,
            language: 'cpp',
            code:':Ldkidm'
          },
          {
            title: 'codewala2',
            id:3,
            language: 'cpp',
            code:':Ldkidmccccccc'
          }
        ]
      }
    ];
    
    const PlaygroundContext = createContext();
    
    function PlaygroundProvider({ children }) {
      const [folders, setFolders] = useState(initialData);
    
      return ( 
        <PlaygroundContext.Provider value={folders}>
          {children}
        </PlaygroundContext.Provider>
      );
    }
    
    
    function Folder({ folderTitle, cards }) {
      return (
        <section>
          <div className="folder-container">
            <div className="folder-header">
              <div className="folder-header-item">
                <span className="material-symbols-outlined" style={{color: "yellow"}}>{folderTitle}</span>
                <span>Folder 1</span>
              </div>
              <div className="folder-header-item">
                <span className="material-symbols-outlined">delete</span>
                <span className="material-symbols-outlined">edit</span>
                <button>
                  <span className="material-symbols-outlined">add</span>
                  <span>New File</span>
                </button>
              </div>
            </div>
          </div>
          <div className="cards-container">
            {cards.map((file) => {
              return (
                <div className="card" key={file.id}>
                  <div className="title-container">
                    <span>{file.title}</span>
                    <span>Language: {file.language}</span>
                  </div>
                  <div style={{display: 'flex', gap: '10px'}}>
                    <span className="material-symbols-outlined">delete</span>
                    <span className="material-symbols-outlined">edit</span>
                  </div>
                </div>
              );
            })}
          </div>
        </section>
      );
    }
    
    function App() {
    
      const folders = useContext(PlaygroundContext);
    
      return (
        <main>
          {folders.map((folder) => {
            return (
              <Folder
                key={folder.id}
                folderTitle={folder.title}
                cards={folder.files}
              />
            );
          })}
        </main>
      );
    
    }
    
    const node = document.getElementById('root');
    const root = ReactDOM.createRoot(node);
    const Root = () => (
      <PlaygroundProvider>
        <App />
      </PlaygroundProvider>
    );
    root.render(<Root />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
    <div id="root"></div>