0

I am trying to get collections using selectors. Here is my code:

Selectors

    import { createSelector } from "reselect";
    
        export const selectShop = state => state.shop;
        
        export const selectCollections = createSelector(
            [selectShop],
            shop => shop.collections
        )
    
    export const selectCollectionForPreview = createSelector(
        [selectCollections],
        collections => Object.keys(collections).map(key => collections[key])
    )
    
    export const selectCollectionItem = collectionUrl => 
        createSelector(
            [selectCollections],
            collections => collections[collectionUrl]
//It seems that the selector above is returning collections as an array instead of object, so collections[collectionUrl] is returning undefined
        )

Component

    const CollectionPage = ({collections}) => {
        // const {title, items} = Object.keys(collections)
        const {title, items} = collections
        console.log('collection', collections);
        
        return(
            // <></>
            <div className="collection-page">
                <h2 className='title'>{title}</h2>
                <div className='items'>
                    {items.map( item => 
                        <CollectionItem key={item.id} item={item}/>
                    )}
                </div>
            </div>
        )
    }
    
    const mapStateToProps = (state,ownProps) => ({
        collections: selectCollectionItem(ownProps.match.params.collectionId)(state)
    })
    
    
    
    export default connect(mapStateToProps)(CollectionPage);

SHOP_DATA

    const SHOP_DATA = {
      hats:{
        id: 1,
        title: 'Hats',
        routeName: 'hats',
        items: [
          {
            id: 1,
            name: 'Brown Brim',
            imageUrl: 'https://i.ibb.co/ZYW3VTp/brown-brim.png',
            price: 25
          },
          {
            id: 2,
            name: 'Blue Beanie',
            imageUrl: 'https://i.ibb.co/ypkgK0X/blue-beanie.png',
            price: 18
          },
          {
            id: 3,
            name: 'Brown Cowboy',
            imageUrl: 'https://i.ibb.co/QdJwgmp/brown-cowboy.png',
            price: 35
          },
          {
            id: 4,
            name: 'Grey Brim',
            imageUrl: 'https://i.ibb.co/RjBLWxB/grey-brim.png',
            price: 25
          },
          {
            id: 5,
            name: 'Green Beanie',
            imageUrl: 'https://i.ibb.co/YTjW3vF/green-beanie.png',
            price: 18
          },
          {
            id: 6,
            name: 'Palm Tree Cap',
            imageUrl: 'https://i.ibb.co/rKBDvJX/palm-tree-cap.png',
            price: 14
          },
          {
            id: 7,
            name: 'Red Beanie',
            imageUrl: 'https://i.ibb.co/bLB646Z/red-beanie.png',
            price: 18
          },
          {
            id: 8,
            name: 'Wolf Cap',
            imageUrl: 'https://i.ibb.co/1f2nWMM/wolf-cap.png',
            price: 14
          },
          {
            id: 9,
            name: 'Blue Snapback',
            imageUrl: 'https://i.ibb.co/X2VJP2W/blue-snapback.png',
            price: 16
          }
        ]
      },
      sneakers:{
        id: 2,
        title: 'Sneakers',
        routeName: 'sneakers',
        items: [
          {
            id: 10,
            name: 'Adidas NMD',
            imageUrl: 'https://i.ibb.co/0s3pdnc/adidas-nmd.png',
            price: 220
          },
          {
            id: 11,
            name: 'Adidas Yeezy',
            imageUrl: 'https://i.ibb.co/dJbG1cT/yeezy.png',
            price: 280
          },
          {
            id: 12,
            name: 'Black Converse',
            imageUrl: 'https://i.ibb.co/bPmVXyP/black-converse.png',
            price: 110
          },
          {
            id: 13,
            name: 'Nike White AirForce',
            imageUrl: 'https://i.ibb.co/1RcFPk0/white-nike-high-tops.png',
            price: 160
          },
          {
            id: 14,
            name: 'Nike Red High Tops',
            imageUrl: 'https://i.ibb.co/QcvzydB/nikes-red.png',
            price: 160
          },
          {
            id: 15,
            name: 'Nike Brown High Tops',
            imageUrl: 'https://i.ibb.co/fMTV342/nike-brown.png',
            price: 160
          },
          {
            id: 16,
            name: 'Air Jordan Limited',
            imageUrl: 'https://i.ibb.co/w4k6Ws9/nike-funky.png',
            price: 190
          },
          {
            id: 17,
            name: 'Timberlands',
            imageUrl: 'https://i.ibb.co/Mhh6wBg/timberlands.png',
            price: 200
          }
        ]
      },
      jackets:{
        id: 3,
        title: 'Jackets',
        routeName: 'jackets',
        items: [
          {
            id: 18,
            name: 'Black Jean Shearling',
            imageUrl: 'https://i.ibb.co/XzcwL5s/black-shearling.png',
            price: 125
          },
          {
            id: 19,
            name: 'Blue Jean Jacket',
            imageUrl: 'https://i.ibb.co/mJS6vz0/blue-jean-jacket.png',
            price: 90
          },
          {
            id: 20,
            name: 'Grey Jean Jacket',
            imageUrl: 'https://i.ibb.co/N71k1ML/grey-jean-jacket.png',
            price: 90
          },
          {
            id: 21,
            name: 'Brown Shearling',
            imageUrl: 'https://i.ibb.co/s96FpdP/brown-shearling.png',
            price: 165
          },
          {
            id: 22,
            name: 'Tan Trench',
            imageUrl: 'https://i.ibb.co/M6hHc3F/brown-trench.png',
            price: 185
          }
        ]
      },
      womens:{
        id: 4,
        title: 'Womens',
        routeName: 'womens',
        items: [
          {
            id: 23,
            name: 'Blue Tanktop',
            imageUrl: 'https://i.ibb.co/7CQVJNm/blue-tank.png',
            price: 25
          },
          {
            id: 24,
            name: 'Floral Blouse',
            imageUrl: 'https://i.ibb.co/4W2DGKm/floral-blouse.png',
            price: 20
          },
          {
            id: 25,
            name: 'Floral Dress',
            imageUrl: 'https://i.ibb.co/KV18Ysr/floral-skirt.png',
            price: 80
          },
          {
            id: 26,
            name: 'Red Dots Dress',
            imageUrl: 'https://i.ibb.co/N3BN1bh/red-polka-dot-dress.png',
            price: 80
          },
          {
            id: 27,
            name: 'Striped Sweater',
            imageUrl: 'https://i.ibb.co/KmSkMbH/striped-sweater.png',
            price: 45
          },
          {
            id: 28,
            name: 'Yellow Track Suit',
            imageUrl: 'https://i.ibb.co/v1cvwNf/yellow-track-suit.png',
            price: 135
          },
          {
            id: 29,
            name: 'White Blouse',
            imageUrl: 'https://i.ibb.co/qBcrsJg/white-vest.png',
            price: 20
          }
        ]
      },
      mens:{
        id: 5,
        title: 'Mens',
        routeName: 'mens',
        items: [
          {
            id: 30,
            name: 'Camo Down Vest',
            imageUrl: 'https://i.ibb.co/xJS0T3Y/camo-vest.png',
            price: 325
          },
          {
            id: 31,
            name: 'Floral T-shirt',
            imageUrl: 'https://i.ibb.co/qMQ75QZ/floral-shirt.png',
            price: 20
          },
          {
            id: 32,
            name: 'Black & White Longsleeve',
            imageUrl: 'https://i.ibb.co/55z32tw/long-sleeve.png',
            price: 25
          },
          {
            id: 33,
            name: 'Pink T-shirt',
            imageUrl: 'https://i.ibb.co/RvwnBL8/pink-shirt.png',
            price: 25
          },
          {
            id: 34,
            name: 'Jean Long Sleeve',
            imageUrl: 'https://i.ibb.co/VpW4x5t/roll-up-jean-shirt.png',
            price: 40
          },
          {
            id: 35,
            name: 'Burgundy T-shirt',
            imageUrl: 'https://i.ibb.co/mh3VM1f/polka-dot-shirt.png',
            price: 25
          }
        ]
      }
    };

export default SHOP_DATA;

Please provide any pointers or advice on what am I doing wrong? I keep getting the error. It seems that the collection is undefined. I don't understand why. Ideally it should return an object.

James Z
  • 12,209
  • 10
  • 24
  • 44
SnehaPk
  • 11
  • 3
  • 1
    Looks like collections **is** undefined, maybe you load it asynchronously or it's located somewhere else in the state. You can check the devtools to see what actions are dispatched and what changes they made to the state. – HMR Sep 09 '21 at 06:46
  • the amount of data in `SHOP_DATA` makes your question difficult to read, consider using just enough data to show the shape, mayby just 1 or 2 records for each category, this will make your code much easier for people to read – Nigel Savage Sep 14 '21 at 15:55

1 Answers1

0

You are exporting the component like this

const mapStateToProps = (state,ownProps) => ({
     collections: selectCollectionItem(ownProps.match.params.collectionId)(state)
})

export default connect(mapStateToProps)(CollectionPage);

The ownProps.match.params.collectionId might be undefined.

Add this at the top of your file

import { withRouter} from 'react-router-dom'

and export your component like

export default connect(mapStateToProps)(withRouter(CollectionPage));
Shrey
  • 11
  • 2
  • Hi, ownProps.match.params is returning values and the selector is somehow converting the collections into array. – SnehaPk Sep 10 '21 at 00:45