1

I'm having a tough time removing data from firebase via user input. I'm able to successfully push data to firebase using this path:

const dbRef = firebase.database().ref('users/' + userName + "/" + category);

I've tried to remove it from the same path, and also by using:

removeItem(itemToRemove) {
    const userName = this.props.userName;        
    console.log(itemToRemove);
    const database = firebase.database().ref('users/' + userName + "/" + category );
    database.child(itemToRemove).remove();
}

...

<button onClick={() => props.removeItem(props.data.key)}>Remove Item</button>

Nothing I've tried has been successful; right now I'm getting this error: Uncaught TypeError: props.removeItem is not a function. My instinct is that I'm somehow missing firebase keys that I would use to handle my items in the data base, but I just can't seem to figure out how to integrate them or use them to delete.

Here's how it's organised in firebase:

enter image description here

Any advice?? I'd really appreciate any suggestions! Thanks!

Here's the rest of the code for the component I'm using if you want to look through it:

import React from 'react';
import ReactDOM from 'react-dom';

class AddClothing extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            items: [],
            text: "",
            initialItems: []
        };

        this.handleTextChange = this.handleTextChange.bind(this);
        this.handleAddItem = this.handleAddItem.bind(this);
        this.removeItem = this.removeItem.bind(this);
        this.getStoredData = this.getStoredData.bind(this);
        this.category = "clothing";
    }
    handleTextChange(event) {
        this.setState({
            text: event.target.value
        });
    }
    handleAddItem(event) {
        event.preventDefault();
        //issue an ID number using the date
        const newItem = {
            id: Date.now(),
            text: this.state.text,
            done: false
        };

        const userName = this.props.userName;
        const category = "clothing"
        const database = firebase.database().ref('users/' + userName + "/" + category);
        database.push(newItem.text);

        this.setState((prevState) => ({
            items: prevState.items.concat(newItem),
            text: ""
        }));
    }

    removeItem(itemToRemove) {
        const userName = this.props.userName;        
        console.log(itemToRemove);
        const database = firebase.database().ref('users/' + userName + "/" + category );
        database.child(itemToRemove).remove();
    }
    getStoredData() {
        const userName = this.props.userName;
        const category = "clothing"
        const dbRef = firebase.database().ref('users/' + userName + "/" + category);
        if (this.props.userName) {
            dbRef.on("value", (firebaseData) => {
                const itemsArray = [];
                const itemsData = firebaseData.val();

                for (let itemKey in itemsData) {
                    itemsArray.push(itemsData[itemKey])
                }

                this.setState({
                    initialItems: itemsArray
                }, () => console.log(this.state.initialItems));
            });
            {
                this.state.initialItems.map((item, i) => {
                    console.log(this.state.initialItems[i]);
                })
            }
        }
    }
    render() {
        return (
            <div className="main-category">
                <div className='inner-wrapper'>

                <h3 className="item-category">Clothing</h3>
                <ul className="items">
                    {this.state.initialItems.map((item, i) => {
                            console.log(this.state.initialItems);
                            return <ClubItem data={this.state.initialItems[i]} key={this.state.initialItems[i]} remove={this.removeItem} />
                    })}
                </ul>
                <form action="">
                    <input type="text" className="form-control" onChange={this.handleTextChange} value={this.state.text} />
                    <button className="btn btn-primary" onClick={this.handleAddItem} disabled={!this.state.text}>{"Add #" + (this.state.items.length + 1)}</button>
                </form>
                </div>
            </div>
        );
    }
}

export function ClubItem(props) {
        return(
            <li className="club-item">
                <input type="checkbox" className="form-check-input"/>
                {props.data}
                <button onClick={() => props.removeItem(props.data.key)}>Remove Item</button>
            </li>
        )
    }

export default AddClothing
5
  • should it be props.removeItem(...), not props.remove(...) ? Commented Jan 14, 2018 at 17:56
  • @danh Ah, thanks for pointing that out! A typo on my part, I've been furiously trying so many things that I must have gotten confused. Unfortunately, it still doesn't work with that change. Now I get this error: "Uncaught TypeError: props.removeItem is not a function " Commented Jan 14, 2018 at 18:12
  • I'm not too sharp in react, I think that it might be this.removeItem() Also note @Frank's advice below that in that function, there's no need to send a param to remove() Commented Jan 14, 2018 at 18:19
  • @danh thanks for the suggestion! Still not doing the trick though, getting another error: "Uncaught TypeError: Cannot read property 'removeItem' of undefined at onClick" Commented Jan 14, 2018 at 18:31
  • 1
    in the ClubItem function above you refer to props.removeItem(props.data.key), but in the parent add clothing component the <ClubItem/> component has a prop named remove. You need to change the prop name to removeItem={...}. Both the prop names need to match, at the moment you are referring to something that doesn't exist, it is undefined (hence the error 'Cannot read property 'removeItem' of undefined'). You also need to bind this correctly in the ClubItem function, as @Frank points out below. Commented Jan 14, 2018 at 21:09

1 Answer 1

2

The Reference.remove() method takes no parameter to indicate what child to remove. You instead call remove() on the exact reference you want to remove. So in your case:

database.child(itemToRemove).remove();

For this error:

Uncaught TypeError: Cannot read property 'props' of undefined at onClick"

You can't just call props in the JSX of your render method. It needs to be this.props:

export function ClubItem(props) {
    return(
        <li className="club-item">
            <input type="checkbox" className="form-check-input"/>
            {props.data}
            <button onClick={() => this.props.removeItem(this.props.key)}>Remove Item</button>
        </li>
    )
}
Sign up to request clarification or add additional context in comments.

6 Comments

Seems like the OP is having trouble entering the function that does the remove. I think in JS, it's harmless (though indicative of misunderstanding) to send a param to a function that doesn't accept one.
Thanks for the response! I made that change, still not quite working though. Currently using "<button onClick={() => this.props.removeItem(props.data)}>Remove Item</button>" to try to remove the item, but getting this error: "Uncaught TypeError: Cannot read property 'props' of undefined at onClick"
@danh: it's slight different (I updated my answer). Reference.remove() takes an argument, just not what the code is passing into it.
@gabycodes I added a possible explanation for that error. But note that Stack Overflow is a horribly inefficient interactive debugging tool and there's quite a bit of code and commented out code in your question. It'd be much easier to help if you stick to a single question and limit the code to the minimum needed to reproduce the problem for that question.
@frankvanpuffelen I tried that change (which makes sense) but still missing something. Error: "dev\scripts\components\AddClothing.js:148 Uncaught TypeError: Cannot read property 'props' of undefined at onClick". Thanks for the tip about shortening the code, will do that now!
|

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.