0

I am getting an error when I click the button. it becomes weird because some it works and other times it doesn't.

import React from 'react';
class Profile extends React.Component{
    constructor(){
        super();
        this.state={
            posts:[],
        }
        this.increase = this.increase.bind(this);
    }
    increase(event){
        event.preventDefault();
        var name = event.target.name;
        var post = name.split(':')[0];
        var applaused =name.split(':')[1];
        var k = name.split(':')[2];
        //some related code
    }
    render(){
        var posts=[];
                var k=-1;
                posts = this.state.posts.map((post)=>{
                   k++;
                   var namek=`${post._id}:${post.applaused}:${k}`
                   var applause=post.applaused=='applause'?<p>applause</p>:<p>applaused</p>
                return(
                <div key={post._id}>
                    <p>{post.post}</p>
                <button onClick={this.increase} name={namek}>{applause}</button>
                })
        return(
            <div>
                {posts}
            </div>
        )
    }
}

export default Profile; 

The error I am getting is-:

Cannot read property split of undefined at line-: 13

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

3 Answers3

0

To avoid error "Cannot read property split of undefined" you need to check if your variable name is defined like this:

if(name !== undefined) {
  // now you are sure that name is defined
}

== Side thoughts ==

Moreover, I'd rather split name once and then get every element from array:

if(name !== undefined) {
  const nameSplitted = name.split(':');
  var post = nameSplitted[0];
  var applaused = nameSplitted[1];
  var k = nameSplitted[2];
}
Marek Szkudelski
  • 1,102
  • 4
  • 11
0

The event target depends on the actual element you click. Sometimes this element seems to have no name attribute. So you cannot use the String#split method if event.target.name is undefined.

For debugging I would log the element.target and name value, before trying to split name, to see what element is the target and what name attribute it has.

    var name = event.target.name;
    console.log("Target is:", event.target, "and it's name is", name);
    var post = name.split(':')[0];

If you want to fix your error, you can check, if the element has no attribute name. There are multiple ways to do that, in this case...

  • if (!event.target.hasAttribute('name')) { // no name
  • if (!('name' in event.target)) { // no name
  • if (event.target.name === undefined) { // no name
  • if (typeof event.target.name === 'undefined') { // no name
Niklas E.
  • 1,848
  • 4
  • 13
  • 25
0

In the increase function you are using the event.target.

Because you have a button tag that contains a p tag it is possible that the event.target is sometime the p tag. It depends on where the user clicks in the button. The p tag has no name attribute so when the user clicks on the p tag inside the button the value is undefined.

You want to always get the button tag in the increase function. You can do that by using event.currentTarget. The currentTarget is always the tag on which the onClick attribute is set.

In conclusion: Use event.currentTarget.name instead of event.target.name so you will always get the value of the name attribute of the button tag.

increase(event){
    var name = event.currentTarget.name;
}

More info about event.target vs event.currentTarget can be found in this StackOverflow answer: https://stackoverflow.com/a/37578174/1375229

A code snippet demonstrating the difference between event.target vs event.currentTarget:

function increase(event) {
  alert(
    'event.target: ' + event.target.tagName + '\n' +
    'event.currentTarget: ' + event.currentTarget.tagName
  )
}
button {
  background: #faa;
}

p {
  background: #aaf;
  padding: 10px;
}
<button onClick="increase(event)">
  The button tag
  <p>The p tag</p>
</button>
Wezelkrozum
  • 831
  • 5
  • 15