SkyeBoniwell
SkyeBoniwell

Reputation: 7092

update a component after axios post

I have a React page that uses axios to upload media.

It uploads fine, but I can't get the page to re-load or update.

In the main, parent page, I have a component for uploading the media (MediaUpload) and one for showing the media (MediaPlayer).

When the upload is successful, I want the MediaPlayer component to update and show the newly uploaded media file name.

Right now, when it uploads, I have to refresh the browser in order to see the new file.

Am I missing anything to make this work?

Thanks!

--parent--

<div> -- Media -- </div>
<div>
</div>
<div>
    <MediaUpload alienId={alien.id} />
</div>
<div>
    <MediaPlayer alienId={alien.id} />
</div>

--MediaUpload--

import React, { Component } from 'react';
import axios from 'axios';

class MediaUpload extends Component {

state = { selectedFile: null }

uploadHandler = (e) => {
    e.preventDefault();

    var bodyFormData = new FormData();

    bodyFormData.append('fileData', this.state.selectedFile);

    axios({
        method: 'post',
        url: `/api/HangingPlanet/alien-files/${this.props.alienId}/files/upload`,
        data: bodyFormData,
        config: { headers: { 'Content-Type': 'multipart/form-data' } }
    })
        .then((response) => {
            //handle success
            console.log(response);
            this.setState({ selectedFile: event.target.files[0] })
        })
        .catch((response) => {
            //handle error
            console.log(response);
        });

}

render() {
    const { alienId } = this.props;

    return (
        <div>
            <div>Upload Media</div>
            <input type="file" name="fileData" multiple />
            <button onClick={this.uploadHandler}>Upload!</button>
        </div>
    );
}
}

export default MediaUpload;

--MediaPlayer--

import React, { Component } from 'react';
import axios from 'axios';
import RenderalienMedia from './RenderalienMedia';

const mediaPath = "/api/HangingPlanet/alien-files/";

class MediaPlayer extends Component {
constructor() {
    super();
    this.state = {
        files: []
    };
}

componentDidMount() {
    axios.get(`/api/HangingPlanet/alien-files/${this.props.alienId}/files`)
        .then((response) => {
            this.setState({ files: response.data })
        })
        .catch((error) => {
            console.log(error);
        });
}

showMedia = (props) => {
    const { alienId } = this.props;
    return (
        <div>
            {
                props.files.length > 0 &&
                    <div>
                    {props.files.map((file) =>
                        <RenderalienMedia
                            mediaPath={mediaPath}
                            alienId={alienId}
                            fileId={file.id}
                            downloadName={file.downloadName}
                            fileTitle={file.title}
                        />
                    )}
                    </div>
            }
        </div>
    );
}

render() {
    const { alienId } = this.props;
    return (
        <div>
            <div>alien Media</div>
            <div>
                {this.showMedia(this.state)}
            </div>
        </div>
    );
}
}

 export default MediaPlayer;

Upvotes: 2

Views: 3945

Answers (2)

Rizal Ibnu
Rizal Ibnu

Reputation: 443

You should tell Parent component to rerender MediaPlayer when upload is completed.

-- Parent --

class Parent extends Component {
    state = {
    showMediaPlayer: false,
    loading: false,
  }

  handleOnUpload = () => {
   this.setState({
   showMediaPlayer: false,
   loading: true,
   });
  }

  handleOnUploadEnd = () => {
   this.setState({
   showMediaPlayer: true,
   loading: false,
   });
  }

  render(){
    return (
        <div> -- Media -- </div>
        <div>
        </div>
        <div>
            <MediaUpload
              alienId={alien.id}
              onUpload={this.handleOnUpload}
              onUploadEnd={this.handleOnUploadEnd}
             />
        </div>
        <div>
            {this.state.loading === true && this.state.showMediaPlayer === false  && 'Loading...'}
            {this.state.loading === false && this.state.showMediaPlayer === true  && <MediaPlayer alienId={alien.id} />}
        </div>
      );
    }
}

-- Media Upload --

class MediaUpload extends Component {

state = { selectedFile: null }

uploadHandler = (e) => {
    e.preventDefault();

    // call handleOnUpload Function on Parent to create loading component
    this.props.onUpload();

    var bodyFormData = new FormData();

    bodyFormData.append('fileData', this.state.selectedFile);

    axios({
        method: 'post',
        url: `/api/HangingPlanet/alien-files/${this.props.alienId}/files/upload`,
        data: bodyFormData,
        config: { headers: { 'Content-Type': 'multipart/form-data' } }
    })
        .then((response) => {
            //handle success
            console.log(response);
            this.setState({ selectedFile: event.target.files[0] })

            // call handleOnUploadEnd Function on Parent to render media player
            this.props.onUploadEnd();
        })
        .catch((response) => {
            //handle error
            console.log(response);
        });

}

render() {
    const { alienId } = this.props;

    return (
        <div>
            <div>Upload Media</div>
            <input type="file" name="fileData" multiple />
            <button onClick={this.uploadHandler}>Upload!</button>
        </div>
    );
}
}

Upvotes: 1

joknawe
joknawe

Reputation: 1540

this.setState({ selectedFile: event.target.files[0] })

event.target.files[0] should be e.target.files[0]

Upvotes: 1

Related Questions