Reputation: 217
I'm working on uploading images on my react app, the idea is to save the images in my object, send it to my back end and upload them to clodinary but right now i cant seem to put the files in my object array:
Component:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone';
import {
Grid,
Row,
Col,
FormControl,
FormGroup,
Button,
ButtonToolbar,
Label
} from 'react-bootstrap';
import {Dwelling} from '../../../model';
import {requestSaveDwelling} from '../../../actions';
class New3 extends Component {
static propTypes = {
requestSaveDwelling: PropTypes.func.isRequired,
history: PropTypes.shape({
push: PropTypes.func.isRequired
}).isRequired,
dwelling: PropTypes.shape({})
};
static defaultProps = {
dwelling: new Dwelling()
};
constructor(props) {
super(props);
this.state = {dwelling: new Dwelling()};
if (this.props.dwelling) {
this.state = this.props;
}
}
handleChange({target: {id, value}}) {
this.setState(
state => ({
dwelling: (Object.assign(state.dwelling, {[id]: value}))
})
);
}
handleDrop(file) {
this.setState(
state => ({
dwelling: (Object.assign(state.dwelling.images, file))
})
);
}
handleSubmit() {
const {dwelling} = this.state;
this.props.requestSaveDwelling(dwelling);
this.props.history.push('/dwellings/latest');
}
render() {
const {dwelling} = this.state;
console.log(dwelling);
return (
<Grid className="animated fadeIn">
<Row>
<Col sm={12}>
<h2>Carga de Imágenes</h2>
<Dropzone
onDrop={this.handleDrop}
multiple
accept="image/*"
>
<p>Arrastre Imagenes aquí, o haga click para seleccionar imagenes.</p>
</Dropzone>
{this.state.dwelling.images.length > 0 ?
<div>
<h2>Uploading {this.state.dwelling.images.length} files...</h2>
<div>{this.state.dwelling.images.map(file => <img src={file.preview}/>)}</div>
</div> : null}
</Col>
</Row>
<Row>
<Col sm={12}>
<FormGroup controlId="occupationStatus">
<Label>Estado Ocupacional</Label>
<FormControl
componentClass="select"
value={dwelling.occupationStatus}
placeholder="Seleccione"
onChange={e => this.handleChange(e)}
>
<option disabled label="Seleccione"/>
<option value="Disponible" label="Disponible"/>
<option value="Alquilada" label="Alquilada"/>
<option value="Vendida" label="Vendida"/>
<option value="Reservada" label="Reservada"/>
<option value="Suspendida" label="Suspendida"/>
</FormControl>
</FormGroup>
</Col>
</Row>
<Row>
<Col sm={12}>
<h2>Descripción General</h2>
<FormGroup controlId="generalDescription">
<FormControl
componentClass="textarea"
value={dwelling.generalDescription}
onChange={e => this.handleChange(e)}
placeholder="Escriba una Descripcion general"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col sm={12}>
<h2>Descripción Privada</h2>
<FormGroup controlId="privateDescription">
<FormControl
componentClass="textarea"
value={dwelling.privateDescription}
onChange={e => this.handleChange(e)}
placeholder="Escriba una Descripcion privada"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col sm={6}>
<ButtonToolbar className="pull-left">
<Button href="#/dwellings/new2">Atrás</Button>
</ButtonToolbar>
</Col>
<Col sm={6}>
<ButtonToolbar className="pull-right">
<Button onClick={() => this.handleSubmit()}>Guardar</Button>
</ButtonToolbar>
</Col>
</Row>
</Grid>
);
}
}
export default connect(
state => ({
dwelling: state.dwelling.dwelling
}),
dispatch => ({
requestSaveDwelling: dwelling => dispatch(requestSaveDwelling(dwelling))
})
)(New3);
object model:
export default class Dwelling {
_id = undefined;
publicationType = '';
address = {
address: '',
latitude: null,
longitude: null
}
images = [];
constructor(obj) {
Object.assign(this, obj);
}
}
when i try to upload an image i get this error: New3.js:51 Uncaught TypeError: Cannot read property 'images' of undefined at Dropzone. (New3.js:51)
Upvotes: 0
Views: 4674
Reputation: 1721
This is my example of my previewer with FileReader. However, this is only one file so you might want to adjust it for your app.
class Preview extends React.Component {
constructor(props) {
super(props);
this.state = {
previewSrc: ''
}
}
handlePreview = (e) => {
e.preventDefault();
let file = e.target.files[0];
let reader = new FileReader();
if (e.target.files.length === 0) {
return;
}
reader.onloadend = (e) => {
this.setState({
previewSrc: [reader.result]
});
}
reader.readAsDataURL(file);
}
render() {
return (
<div id="previewer">
<input type="file" onChange={this.handlePreview} />
<h1>Preview</h1>
<img src={this.state.previewSrc} alt="" />
</div>
);
}
}
ReactDOM.render(<Preview/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
<div id="root"></div>
Upvotes: 2