0

What I have now: As of now in my Storybook file, I create an array and pass it through as a property of my component.

What I am trying to achieve: However, I wish to simply pass length as a prop and then an array gets created dynamically from 1 to length and then display that instead of using an entire object array as a prop. I am not sure how I would do that here.

Here is my setup of my project as I have it now, which is to create an array as a prop, grab the storybook dummy array data, transfer it over and then display it which just seems a mess to me, but all my attempts to dynamically do this result in errors and confusion.

I want orderCount to be a number, then use that number to create a new array of length orderCount and from 1 to orderCount, and then map that. The problem here is I want to do this in displayOrders, but I don't know how to do anything before the .map() in the function.


Storybook:

import {LoyaltyStatus} from '@molecules/LoyaltyStatusCard';
import {storiesOf} from '@storybook/react-native';
import React from 'react';

const dummy = [
  {id: 1},
  {id: 2},
  {id: 3},
  {id: 4},
  {id: 5},
  {id: 6},
  {id: 7},
  {id: 8},
  {id: 9},
];

storiesOf('Loyalty Status', module).add('Default', () => (
  <LoyaltyStatus
    statusTier="Gold"
    points={10}
    orderCount={dummy.map((order) => ({
      orderNumber: order.id,
    }))}
    filled={7}
  />
));


React-native Typescript component:

import * as React from 'react';
import styled from '@styled-components';
import {Text, TextTypes} from '@atoms/Text';
import Icon from 'react-native-vector-icons/FontAwesome5';

export interface ILoyaltyStatusProps {
  orderCount: {
    orderNumber: number;
  }[];
  filled: number;
  statusTier: string;
  points: number;
}

export const LoyaltyStatus: React.FC<ILoyaltyStatusProps> = ({
  orderCount,
  filled,
  statusTier,
  points,
  ...props
}) => {
  const displayOrders = () =>
    orderCount.map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS.orderNumber}</OrderText>
        {ORDERS.orderNumber <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));

  return (
    // eslint-disable-next-line react/jsx-props-no-spreading
    <Container {...props}>
      <InnerContainer>
        <MainContentContainer>
          <TitleText>{`Unlock ${statusTier} Status`}</TitleText>
          <SubText>{`Just order ${orderCount.length} times this month.`}</SubText>
          <OrderContainer>{displayOrders()}</OrderContainer>
        </MainContentContainer>
        <FooterContentContainer>
          <PointsText>
            {`You'll earn ${points} points per dollar when you unlock ${statusTier} Status.`}
          </PointsText>
        </FooterContentContainer>
      </InnerContainer>
      <IconContainer>
        <LockIcon />
      </IconContainer>
    </Container>
  );
};

Edit: My final solution was to do this, but the answers really helped me achieve this. I went with this solution as I thought it made more sense to me and was clearer to read

const populateArray = (length: number) => {
    const newArr = new Array(length);
    for (let i = 1; i <= length; i++) {
      newArr[i] = i;
    }
    return newArr;
  };

  const displayOrders = () =>
    populateArray(orderCount).map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS}</OrderText>
        {ORDERS <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));

1 Answer 1

2

You can add getDummyArray function like this:

const getDummyArray = (length) => {
    return length > 0
      ? [...Array(length)].map((_, idx) => ({ id: idx + 1, orderNumber: idx + 1 }))
      : [];
  };

So it becomes like this:

export const LoyaltyStatus: React.FC<ILoyaltyStatusProps> = ({
  orderCount,
  filled,
  statusTier,
  points,
  ...props
}) => {

const getDummyArray = (length) => {
    return length > 0
      ? [...Array(length)].map((_, idx) => ({ id: idx + 1, orderNumber: idx + 1 }))
      : [];
  };

  const displayOrders = () =>
    getDummyArray(orderCount).map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS.orderNumber}</OrderText>
        {ORDERS.orderNumber <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));
Sign up to request clarification or add additional context in comments.

9 Comments

Where would I call getDummyArray() in my code? I need it to populate before displayOrders() so I can map it? Also can you explain this code a little bit?
Where you want to pass length? in LoyaltyStatus as prop ?
Yes, length is a prop called orderCount: number. I want to pass it like that so the backend defines the length by a number and then it creates an array of that length.
Updated answer, in that function we make empty array of length length. Then fill it with objects as you want: { id: idx + 1, orderNumber: idx + 1 }
_ is empty array item, we dont need it so it has kinda empty name. Because we dont use it. It can be named as item. Next idx is array's index. Can read here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.