0

I'm trying to create a song uploading function using Axios in order to send the data to my server.

The backend requires audio file, image file and name for a single track. So now, if I input an image file, react can recognize that image, but then I input an audio file, It throws me an error:

Uncaught TypeError: Cannot read property '0' of null

Here is my code:

export default class Uploader2 extends Component {

  constructor(props) {
    super(props);
    this.state = {
      audio: null,
      image: null,
      name: ""
    };
    this.onFormSubmit = this.onFormSubmit.bind(this);
    this.onChangeHandler = this.onChangeHandler.bind(this);
    this.fileUpload = this.fileUpload.bind(this);
  }

  onFormSubmit(e) {
    e.preventDefault();
    this.fileUpload(this.state.audio, this.state.image, this.state.name).then(
      response => {
        console.log(response.data);
      }
    );
  }

  onChangeHandler(e) {
    this.setState({
      audio: e.target.files[0],
      image: e.target.files[1],
      name: e.target.value
    });
  }

  fileUpload(audio, image, name) {
    const url = "https://xxxx.xx.xxx/api/songs";
    const formData = new FormData();
    formData.append("audio", audio);
    formData.append("image", image);
    formData.append("name", name);
    const config = {
      headers: {
        "content-type": "multipart/form-data",
        Authorization: "Bearer xxxxxxx"
      }
    };
    return axios.post(url, formData, config);
  }

  render() {
    return (
      <form onSubmit={this.onFormSubmit}>
        <h1>File Upload</h1>
        <input
          type="file"
          name="audioUpload"
          onChange={this.onChangeHandler}
          multiple
        />
        <input type="file" name="imageUpload" onChange={this.onChangeHandler} />
        <input type="text" name="name" onChange={this.onChangeHandler} />
        <button type="submit">Upload</button>
      </form>
    );
  }
}

I have tested this feature with postman and It worked fine, so the bug must be in this code. Please help

1 Answer 1

1

Looks like the error is being thrown in that line:

e.target.files[0]

It's because e.target.files can be null - for instance, if you open the select file window and click cancel. I suggest you to check against null value and not to setState if there is no files selected:

onChangeHandler(e) {
  if(!e.target.files) {
    return;
  }

    this.setState({
      audio: e.target.files[0],
      image: e.target.files[1],
      name: e.target.value
    });
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for pointing it out, but a new error occured, the image in the current state is still undefined and we are just changing the audio and name property, the audio property is carrying file object (whether a audio or image file), and the name property is carrying the file's source path.
I suggest you split image and audio upload as it's unintuitive. So create separate upload for both of them - it will be easier for you to handle the changes. As for the name property - what value should that be?
You are right, I want to create a reusable code but It didn't work. Thanks for your suggestion.

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.