the end of all albums
click add album
complete form with file input
new album is added
detailed file info and form data
import React, { Component } from 'react';
import '../App.css';
import { Switch, Route } from 'react-router-dom';
import Albums from '../pages/albums';
import Login from '../pages/login';
import Logout from '../pages/logout';
import AlbumDetail from '../pages/albumDetail';
import AlbumForm from '../pages/albumForm';
export default class Body extends Component {
render() {
return (
<main className='Body-Background'>
<Switch>
<Route exact path='/' component={Albums} />
<Route path='/login/' component={Login} />
<Route path='/logout/' component={Logout} />
<Route path='/albumDetail/' component={AlbumDetail} />
<Route path='/addAlbum/' component={AlbumForm} />
</Switch>
</main>
);
}
}
--------------------------------
//pages/albumForm
import React, { Component } from 'react';
import '../App.css';
import { Input } from 'antd';
import { FaOpencart, FaLyft, FaSignature } from "react-icons/fa";
import { Button } from 'reactstrap';
import { connect } from 'react-redux';
import { postAlbum } from '../redux/actions/postAlbum'
import { Redirect } from 'react-router-dom';
import { getAlbums } from '../redux/actions/getAlbums';
import { getUsers } from '../redux/actions/getUser';
class albumForm extends Component {
constructor(props) {
super(props);
this.state = {
artist: '',
album_title: '',
genre: '',
album_logo: null,
message: <p></p>,
};
}
componentDidMount() {
if (this.props.loggedin) {
if (!this.props.gotUsers) {
this.props.dispatch(getUsers(this.props.token));
}
if (!this.props.gotAlbums) {
this.props.dispatch(getAlbums(this.props.token));
}
}
}
inputChange = (e, p) => {
this.setState({ [p]: e.target.value });
}
fileChange = (e) => {
console.log(e.target.files);
this.setState({ album_logo: e.target.files[0] })
}
formSubmit = (e) => {
e.preventDefault();
const data = {
artist: this.state.artist,
album_title: this.state.album_title,
genre: this.state.genre,
author: this.props.users.filter(user => user.username == this.props.username)[0].id,
album_logo: this.state.album_logo,
}
console.log(data);
const formData = new FormData();
formData.set('artist', data.artist);
formData.set('album_title', data.album_title);
formData.set('genre', data.genre);
formData.set('author', data.author);
formData.append('album_logo', data.album_logo);
this.props.dispatch(postAlbum(this.props.token, formData))
//wait for 5sec, check every sec to see if post successful
let i = 0;
const waitPost = setInterval(() => {
if (this.props.added) {
this.setState({ message: <p style={{ color: 'green' }}>Post successful</p> })
clearInterval(waitPost);
}
if (i == 5) {
this.setState({ message: <p style={{ color: 'red' }}>Post timeout</p> })
clearInterval(waitPost);
}
i++;
}, 1000)
}
render() {
if (!this.props.loggedin) {
return <Redirect to='/login' />
}
return (
<form style={{ marginLeft: '10px', width: '300px' }}
onSubmit={(e) => this.formSubmit(e)}>
<legend>Album Form</legend>
<hr />
<p style={{ color: 'red' }}>{this.props.error}</p>
{this.state.message}
<Input placeholder="artist" required='required'
prefix={<FaOpencart style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'artist')}
style={{ marginTop: '5px' }}
/>
<Input placeholder="album title" required='required'
prefix={<FaSignature style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'album_title')}
style={{ marginTop: '15px' }}
/>
<Input placeholder="genre" required='required'
prefix={<FaLyft style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'genre')}
style={{ marginTop: '15px' }}
/>
<div style={{ marginTop: '15px' }}>
Album Logo: <input type='file' required='required'
onChange={(e) => this.fileChange(e)} />
</div>
<Button color="success" type='submit' size='sm'
style={{ marginTop: '15px' }}
>Submit</Button>
</form>
);
}
}
export default connect(
(store) => {
return {
token: store.login.token,
loggedin: store.login.fetched,
added: store.albums.added,
gotAlbums: store.albums.fetched,
albums: store.albums.albums,
gotUsers: store.users.fetched,
users: store.users.users,
username: store.login.username,
error: store.albums.error
};
}
)(albumForm);
---------------------------------------
//redux/actions/postAlbum
import axios from 'axios';
export function postAlbum(token, data) {
return {
type: "add_album",
payload: axios({
method: 'post',
url: 'http://127.0.0.1:8000/api/album_list/',
headers: {
Authorization: 'Token ' + token,
},
data: data,
})
}
}
--------------------------------
//redux/reducers/albumReducer
export default function reducer(
state = {
albums: [],
fetching: false,
fetched: false,
adding: false,
added: false,
error: ''
},
action
) {
switch (action.type) {
case "fetch_albums_PENDING": {
return { ...state, fetching: true, fetched: false, error: '' }
}
case "fetch_albums_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
albums: action.payload.data,
error: ''
}
}
case "fetch_albums_REJECTED": {
return {
...state,
fetching: false,
error: action.payload.toString()
}
}
case "add_album_PENDING": {
return { ...state, adding: true, added: false, error: '' }
}
case "add_album_FULFILLED": {
return {
...state,
adding: false,
added: true,
albums: [...state.albums].concat(action.payload.data),
error: ''
}
}
case "add_album_REJECTED": {
return {
...state,
adding: false,
error: action.payload.toString()
}
}
default:
break;
}
return state;
}
reference:
https://gist.github.com/AshikNesin/e44b1950f6a24cfcd85330ffc1713513
https://stackoverflow.com/questions/47630163/axios-post-request-to-send-form-data
No comments:
Post a Comment