1

I have an array of objects coming from the server. I use this to display cards on the screen. I want to insert an "advertisements card" every X cards. I thought I'd done this on the web with the following code, but it seems to not be working with my react-native app.

class DeckArea extends React.Component {
    constructor(props){
        super(props);
    }
    render(){

        let { data, likeJob } = this.props;

        // place an object into the array of jobs data
        data.jobs.forEach((item, i) => {
            let remainder = i%4;        
            if (remainder === 0) {
                console.log(remainder === 0)
                data.jobs.splice(i, 0,{ isAd: true, _id: uuidV4() })
            }
        });


        return (
            <View style={styles.container}>
                <Swipe
                  data={data.jobs}
                  renderCard={(job) => {
                    //check if isAd === true, 
                    // if so, show the AdCard not the deck card
                    if (job.isAd) {
                        return <AdCard adsManager={adsManager} />
                    }
                    return <DeckCard job={job} isLikedCard={false} />
                  }}
                />
            </View>
        );
    }
}

I've done some quick testing and the problem is definitely happening here:

           data.jobs.forEach((item, i) => {
                let remainder = i%4;        
                if (remainder === 0) {
                    console.log(remainder === 0)
                    data.jobs.splice(i, 0,{ isAd: true, _id: uuidV4()})
                }
            });

resulting in "attempted to assign to readonly property"

Additional resources:

Community
  • 1
  • 1
arcom
  • 612
  • 4
  • 11
  • 18

1 Answers1

2

First of all, by inserting in the original jobs array with data.jobs.splice(), you are modifying an array passed via props, which is considered to be bad practice.

Instead, you should create a new array, which would include job adds. Example code:

// Will show an add after each 4 jobs
const jobsWithAds = data.jobs.reduce((accumulator, job) => {
  const add = { isAd: true, _id: uuidV4() }
  const remainder = accumulator.length % 5; // 5 is needed to include job ad

  // Additional check is required to skip first add
  if (remainder === 0 && accumulator.length > 0) {
    accumulator.concat(add);
  }

  // Add an ad after first 4 jobs, which have no ad
  if (accumulator.length === 4) {
    accumulator.concat(add);
  }

  accumulator.concat(job);
}, [])
Deividas
  • 6,437
  • 2
  • 26
  • 27