Home > OS >  properties.map is not a function when map
properties.map is not a function when map

Time:03-12

I'm getting the error "TypeError: properties.map is not a function", however when i console.log(properties) i can see the data. Can anyone explain me what i'm doing wrong? If i remove the map code obviously the error is not showing. Is it because "properties" is not defined yet during the render? I'm a bit confused of why it's not defined since as i said i can see the data on load with the console.

enter image description here

import React, { Component } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AndroidOutlined, AppleOutlined } from '@ant-design/icons';
import Tabs, { TabPane } from '@iso/components/uielements/tabs';
import Select, { SelectOption } from '@iso/components/uielements/select';
import Button from '@iso/components/uielements/button';
import PageHeader from '@iso/components/utility/pageHeader';
import Box from '@iso/components/utility/box';
import { Form, Input, Checkbox, Col, Row } from 'antd'
import LayoutWrapper from '@iso/components/utility/layoutWrapper.js';
import ContentHolder from '@iso/components/utility/contentHolder';
import IntlMessages from '@iso/components/utility/intlMessages';
import FormGeneral from './FormGeneral';
import FormDetails from './FormDetails';

import propertiesActions from '@iso/redux/properties/actions';
const Option = SelectOption;

const {
  loadFromApi,
} = propertiesActions;

export default function PropertiesPage() {

  const dispatch = useDispatch();
  React.useEffect(() => {
    dispatch(loadFromApi());
  }, [dispatch]);

  const { properties, property, isLoading } = useSelector(
    state => state.Properties
  );

  const rowStyle = {
    width: '100%',
    display: 'flex',
    flexFlow: 'row wrap',
  };
  const colStyle = {
    marginBottom: '16px',
  };
  const gutter = 16;

  // Show data
  console.log(properties);
  console.log(isLoading);

  return (
    <LayoutWrapper>
      <PageHeader>Properties</PageHeader>

      <Box>
        <Tabs defaultActiveKey="1">
          <TabPane
            tab={
              <span>
                <AppleOutlined />
                General
              </span>
            }
            key="1"
          >

          <div>
            {console.log(properties)}
            {properties.map(e =>
              <div key={e.id}>
                {e.id}
              </div>  
            )} 
          </div>

          <Row style={rowStyle} gutter={gutter} justify="start">
            <Col md={12} sm={12} xs={24} style={colStyle}>
              <Box>
                <FormGeneral />
              </Box>
            </Col>
          </Row>

          </TabPane>
          <TabPane
            tab={
              <span>
                <AndroidOutlined />
                Tab 2
              </span>
            }
            key="2"
          >
            <FormDetails />
          </TabPane>
        </Tabs>
      </Box>
    </LayoutWrapper>
  );
}

UPDATED:

properties is empty object at first

enter image description here

CodePudding user response:

What if you try properties?.map, so it doesn't map if it is undefined, and wait until you really get the array. Because I don't have a big knowledge about redux, but from what I can read from your code, I understand that you are getting the properties asynchronously.

CodePudding user response:

By default properties is undefined. .map cannot work with undefined. Try to use:

  const { properties = [], property, isLoading } = useSelector(
    state => state.Properties
  );

It is possible to extend the answer and change the initialState, but your reducer code is needed.

CodePudding user response:

before you map properties you should check if it is undefined because the initial value of state object in react is undefined and I think that if you will roll up in your console you should see an undefined print to the console

<div>
        {console.log(properties)}
        {properties !== undefined ? properties.map(e =>
          <div key={e.id}>
            {e.id}
          </div>  
        ): null} 
      </div>

CodePudding user response:

In fact the object was defined but empty, i had to check for the length

<div>
    {console.log(properties)}
    {properties.length > 1 ? properties.map(e =>
      <div key={e.id}>
        {e.id}
      </div>  
    ): null} 
  </div>

Doing this resolved the issue.

  • Related