Skip to content Skip to sidebar Skip to footer

Feathersjs Cannot Read Property 'find' of Undefined

This is one of the more than common errors yous will run into when starting out with React:

            Cannot read property 'map' of undefined          

In this mail service, we'll learn how to fix it.

Why It'due south Happening

The variable you lot are trying to map over is undefined. It will probably somewhen be an array, but due to the asynchronous nature of React, y'all are experiencing at least 1 return when the variable is undefined.

Let's take this example code. In it, nosotros fetch some data from an API and gear up state with that information.

                          part              MyComponent              (              )              {              const              [information,              setData]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              fetch              (              '/api/data'              )              .              then              (              (              res              )              =>              res.              json              (              )              )              .              and then              (              (              data              )              =>              {              setData              (data)              ;              }              )              .              take hold of              (              (              err              )              =>              {              console.              log              (err)              ;              }              )              ;              }              ,              [              ]              )              ;              return              (                                                <ul                >                                                        {data.              map              (              (              item              )              =>              (                                                <li                key                                  =                  {detail.id}                                >                            {item.name}                                                </li                >                            )              )              }                                                                            </ul                >                            )              ;              }                      

This lawmaking might seem fine, but our data fetching takes some time and React does non wait for the data fetching (or whatsoever async activity) to happen before it get-go renders your JSX. That means, while the data is being fetched, React is trying to run data.map(...).

Since we provided no initial value for information in our useState hook, data is undefined. As we know from the error message, it's problematic to try to call map on undefined!

Fix Selection ane: Default the Variable to an Empty Array

This first quick ready might be enough for your use case: just default your stateful variable to an array while you lot're waiting for your information to fetch. For case:

                          function              MyComponent              (              )              {              // Empty array in useState!              const              [data,              setData]              =              useState              (              [              ]              )              ;              useEffect              (              (              )              =>              {              fetch              (              '/api/data'              )              .              so              (              (              res              )              =>              res.              json              (              )              )              .              then              (              (              data              )              =>              {              setData              (data)              ;              }              )              .              catch              (              (              err              )              =>              {              panel.              log              (err)              ;              }              )              ;              }              ,              [              ]              )              ;              return              (                                                <ul                >                                                        {data.              map              (              (              item              )              =>              (                                                <li                key                                  =                  {item.id}                                >                            {particular.proper noun}                                                </li                >                            )              )              }                                                                            </ul                >                            )              ;              }                      

The reason this works is that, while your data fetching is happening, React will call the map method on an empty data array. This is fine—nothing volition be rendered and there will be no errors. Once the information loads from the API call, our data land will exist gear up and our list will correctly render.

Fix Option 2: Showing a Loading Indicator

While the previous prepare is uncomplicated, it might not exist the best user feel to display nix until the data loads. Instead, nosotros might cull to brandish a loading indicator. There are a few ways nosotros tin can do this, only one of the simpler ways is to just add another stateful variable called loading.

                          office              MyComponent              (              )              {              const              [data,              setData]              =              useState              (              [              ]              )              ;              const              [loading,              setLoading]              =              useState              (              faux              )              ;              useEffect              (              (              )              =>              {              setLoading              (              truthful              )              ;              fetch              (              '/api/data'              )              .              then              (              (              res              )              =>              res.              json              (              )              )              .              then              (              (              data              )              =>              {              setData              (data)              ;              }              )              .              grab              (              (              err              )              =>              {              console.              log              (err)              ;              }              )              .              finally              (              (              )              =>              {              setLoading              (              faux              )              ;              }              )              ;              }              ,              [              ]              )              ;              if              (loading)              {              return                                                <p                >                            Data is loading...                                                </p                >                            ;              }              return              (                                                <ul                >                                                        {data.              map              (              (              item              )              =>              (                                                <li                central                                  =                  {detail.id}                                >                            {detail.proper noun}                                                </li                >                            )              )              }                                                                            </ul                >                            )              ;              }                      

This is pretty simple and constructive! When our information starts to fetch, we prepare loading to true. When it'south done fetching, we set up loading to false. Note that nosotros utilize the finally method on our Promise since that will run regardless of whether the fetch succeeds or fails.

Speaking of Fetch Failures…

We should probably handle the situation in which our fetch fails. Additionally, we can evidence the user an error bulletin if our information variable is not an array. This latter point is important in making sure that we never try to admission the map property on a non-array since it simply won't work.

                          office              MyComponent              (              )              {              const              [data,              setData]              =              useState              (              [              ]              )              ;              const              [loading,              setLoading]              =              useState              (              false              )              ;              const              [fault,              setError]              =              useState              (              )              ;              useEffect              (              (              )              =>              {              setLoading              (              true              )              ;              fetch              (              '/api/information'              )              .              then              (              (              res              )              =>              res.              json              (              )              )              .              and then              (              (              data              )              =>              {              setData              (data)              ;              }              )              .              catch              (              (              err              )              =>              {              setError              (err)              ;              }              )              .              finally              (              (              )              =>              {              setLoading              (              faux              )              ;              }              )              ;              }              ,              [              ]              )              ;              if              (loading)              {              return                                                <p                >                            Information is loading...                                                </p                >                            ;              }              if              (mistake              ||              !Assortment.              isArray              (data)              )              {              return                                                <p                >                            There was an error loading your data!                                                </p                >                            ;              }              return              (                                                <ul                >                                                        {information.              map              (              (              item              )              =>              (                                                <li                key                                  =                  {particular.id}                                >                            {item.name}                                                </li                >                            )              )              }                                                                            </ul                >                            )              ;              }                      

And at present nosotros have a pretty safe way of treatment our async operation without getting the dreaded "cannot read property 'map' of undefined" error!

If you'd similar to support this weblog past ownership me a coffee I'd really capeesh it!

Nick Scialli

hendersonnevency65.blogspot.com

Source: https://typeofnan.dev/fix-cannot-read-property-map-of-undefined-error-in-react/

Post a Comment for "Feathersjs Cannot Read Property 'find' of Undefined"