0

I have done an array.map() that loop through json file (goods.json). Then I want to make some manipulations with it (want to delete item from this array in removeCard(obj) method for example). Render is ok but the problem is that I don't understand why I can't see shoppingCardsJSX array in removeCard(obj) method, always get underfined. I have read answers in How to delete a ToDo Item onClick in React? and Remove item from array in React but unfortunately I didn't understand how it works. Can you please help me find out what I'm doing wrong ? Hope this part of code can illustrate my problem,

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }
    render() {
        console.log("render");
        let shoppingCardsJSX = goods.map((good) => {
            return (
                <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard}
                />
            );
        });
        console.log(shoppingCardsJSX);
        return shoppingCardsJSX;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

2
  • Are you sure goods contains anything? Can you console.log it to be sure? Commented Oct 10, 2018 at 22:45
  • yes, it contains Commented Oct 10, 2018 at 22:47

4 Answers 4

1

It looks like you never set this.shoppingCardsJSX and also you also should use this.removeCard.bind(this) instead of this.removeCard as a prop, because then it can reference this when it is called.

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }
    render() {
        console.log("render");
        this.shoppingCardsJSX = goods.map((good) => {
            return (
                <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard.bind(this)}
                />
            );
        });
        console.log(this.shoppingCardsJSX);
        return this.shoppingCardsJSX;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Sign up to request clarification or add additional context in comments.

1 Comment

@prostyash awesome glad to help!
1

It looks like running the code snippet is returning an error because you're never actually setting shoppingCardsJSX to the component. Your console.log(this.shoppingCardsJSX); statement is causing it to error out

You can always try wrapping it in a div:

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
    }
    render() {
        return (
           <div>
             {
              goods && goods.map((good) => {
                return (
                  <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard}
                  />
                );
              });
            }
        </div>
      )
    }
}

Comments

0

You should use an arrow function to bind the this keyword to removeCard function like this

removeCard = (obj) => {
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }

The other way is to do this

<ShoppingCard
    key = {good.id }
    goodId = {good.id}
    src = {good.src}
    price = {good.price}
    onRemoveCard={this.removeCard.bind(this}
/>

However don't mix the two.

Comments

0

Use Arrow function as they are binded by default. you dont need to bind these arrow functions.

 removeCard=(obj)=>{
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }

Comments

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.