Pre-populate image field in the React js form - javascript

I am new in reactjs. i am trying to update the form. Everything is pre-populating except for image field. So I have displayed image on current image label.
as because image field is not pre-populating, due to this filling up the image have become mandatory.
below is the code
import React, { Component } from 'react';
import axios from 'axios';
import './updateitem.css';
import { Link } from 'react-router-dom';
class updateItem extends Component{
constructor(props){
super(props);
this.state = {
name: '',
description: '',
price: '',
image: '',
message: "",
id: '',
image_to_display: '',
}
}
componentDidMount(){
const itno = this.props.match.params.itno;
const itemAPI = `${window.apiHost}/api/items/${itno}`;
axios.get(itemAPI).then(res => {
this.setState({
name: res.data.result.item_detail.name,
description: res.data.result.item_detail.description,
price: res.data.result.item_detail.price,
image: res.data.result.item_detail.image,
id: res.data.result.item_detail.id,})
})
}
onImageChange= (event)=>{
this.setState({
'image': event.target.files[0],
})
}
handleChange= (event)=>{
this.setState({
[event.target.name]: event.target.value,
})
}
handleUpdate = async (event)=>{
console.log('handle update');
const itno = this.props.match.params.itno;
const itemAPI = `${window.apiHost}/api/items/${itno}/`;
event.preventDefault();
let form_data = new FormData();
form_data.append('name', this.state.name);
form_data.append('description', this.state.description);
form_data.append('price', this.state.price);
form_data.append('image', this.state.image, this.state.image.name);
await axios.put(itemAPI,
form_data, {headers: {
'content-type': 'multipart/form-data'
}}).then(res => {
this.setState({
name: res.data.result.item_detail.name,
description: res.data.result.item_detail.description,
price: res.data.result.item_detail.price,
image: res.data.result.item_detail.image,
id: res.data.result.item_detail.id,
message: res.data.result.message})})
document.getElementById('update_message').innerHTML = this.state.message
}
render(){
return(
<div className="main_div">
<div className="title">
<h1>Welcome to "Sadguru's Amrit-Tulya-Tea Shop"</h1>
</div>
<div id="update_message"></div>
<div className='container con_class'>
<form onSubmit={this.handleUpdate} encType="multipart/form-data" className='update_form'>
<h2>Update Form</h2>
<div className="body">
<div className="name"><p>Name:</p><input type="text" value={this.state.name} onChange={this.handleChange} name="name"></input></div ><br></br>
<div className="desc"><p>Description: </p><textarea type="textarea" value={this.state.description} onChange={this.handleChange} name="description"></textarea></div><br></br>
<div className="price"><p>Price: </p><input type="text" value={this.state.price} onChange={this.handleChange} name="price"></input></div><br></br>
<div className="img"><p>Image: </p><input type="file" className="form-control" id="image" onChange={(e)=>this.onImageChange(e)} name="image" /></div>
<div className="_ext_img">Current Image<img src={this.state.image} alt="Card"/></div>
</div>
<div className="footer">
<button type="submit" className="btn btn-success update" >Update</button>
<Link to={`/items/${this.state.id}/`}>
<button type="button" className="btn btn-danger" >Cancel</button>
</Link>
</div>
</form>
</div>
</div>
)
}
}
export default updateItem;
if i am filling up the form then it gets updated.
i want the image to be prefilled with the data coming from API. and filling up the image should be optional. if user is not filling it up, than same image should be updated.
Please help me on this.
thanks in advance.

You can't have a default value for the file input. This is purposely done for security reasons, otherwise you could upload and submit a malicious file without the user's knowledge.
What you could do instead is work around this issue, e.g. the field doesn't need to be mandatory but you can have a default value for the image in your component's state, and simply add a message (and probably display the image) for the user below the form, that if no file is uploaded, the default one will be used.

It is not possible to pre-fill a file input, an uploaded file has to be selected by user manually. Besides, your API is most likely returns an image url, but file's input value is always a File instance.

Related

Broken icon is displayed for the image with alt text

I have an image called image.jpg inside the src -> images -> image.jpg. I have some problem with my image on my React app. My code is running well but the image does not show up instead on saving and loading the application, the image is not displayed but broken icon is displayed with alt text. How is it possible to solve this problem?
What I have tried is:
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
term: "",
names: [
{ name: "Deepak", job_profile: "Quality Analyst", description: "He is Passionate in Tester" },
{ name: "Deepinder", job_profile: "iOS Developer", description: "He is a Dedicated iOS Developer" }
],
filteredData: [{}]
};
}
render() {
let terms = "";
if (this.state.term) {
terms = this.state.term.toLowerCase();
}
return (
<div className="App">
<label>Search Employee: </label>
<input
type="text"
value={this.state.term}
id="searchEmp"
placeholder="Enter Name"
onChange={(event) => {
if (event.target.value.indexOf(" ") > -1) {
alert("Please don\'t enter space.");
this.setState({ term: "" });
return;
}
this.setState({ term: event.target.value });
}}
/>
<br />
<br />
{this.state.names &&
this.state.names
.filter((x) => x.name.toLowerCase().startsWith(terms) || (x.description.toLowerCase().includes(terms)))
.map((item) => {
return (
<div className="data-body">
<div>Name : {item.name}</div>
<div>Job Profile : {item.job_profile}</div>
<div>Description : {item.description}</div>
<div><img src={require('../src/images/image.jpg')} alt="profile_picture" /></div>
<input type="button" id="button"
value="Delete" onClick={() => {
this.setState
({ names: this.state.names.filter
(i => i.name !== item.name) });
}}/>
<div>{<br></br>}</div>
</div>
);
})}
</div>
);
}
}
export default App;
I assume that you are using create-react-app to bundle your project. If that is the case, you just need to put all your images in the public folder and just mention the name in the src attribute.
You don't need the require function while mentioning the source of an image.
So, your code should look like this:
<img src="image.jpg" alt="profile_picture"/>
If you want the image to reside in some part of your source directory, you can import the image from there and use it in your code as follows:
import Image from '../images/image.jpg'
<img src={Image} alt="profile_picture"/>
Edit
Using ES5 syntax, you could do the following:
const Image = require("../images/image.jpg")
<img src={Image} alt="profile_picture"/>
i hope this helps you
<div>
<img src='../src/images/image.jpg' alt="profile_picture" />
</div>

How do you update individual properties of objects in React component states?

I am creating a simple React app that allows the user to add contacts to a master list. My components state looks like this:
state = {
contact: {
fname: "",
lname: "",
address: "",
phone: "",
email: "",
id: ""
}
};
So far, I have been able to effectively add properties such as name, email, etc using values sent from inputs.
this.setState({
contact: {
...this.state.contact,
[e.target.name]: e.target.value // e is an event sent from an input
}
});
};
That's all fine and dandy, but I need each contact to have a unique ID. I have been trying to tack on the ID to the contact object before I send it up the component hierarchy.
const unId = new Date().getTime();
this.setState({
contact: {
...this.state.contact,
id: unId
}
});
This code is producing some strange issues and I'm not sure why. When I run it for the first time, the id is generated, but not assigned to the contact. The second time I run it, the id produced the first time is assigned to the second contact. In other words, the id property is updating the state later one cycle behind the time it should.
I'm not very familiar with synchronicity or anything in React, so I would really appreciate any help I could get.
Does this example help you? If not, can you comment what do you exactly want?
https://codesandbox.io/s/priceless-mccarthy-7i69e
import React, { Component } from "react";
class App extends Component {
state = {
contact: {
fname: "",
lname: "",
address: "",
phone: "",
email: "",
id: new Date().getTime()
}
};
handleInputChange = e => {
this.setState({
contact: {
...this.state.contact,
[e.target.name]: e.target.value
}
});
};
handleSubmit = e => {
console.log(this.state);
};
render() {
const { fname, lname, address, phone, email, id } = this.state.contact;
return (
<div>
<label>fname</label>
<input
type="text"
value={fname}
name="fname"
onChange={this.handleInputChange}
/>
<br />
<label>lname</label>
<input
type="text"
value={lname}
name="lname"
onChange={this.handleInputChange}
/>
<br />
<label>address</label>
<input
type="text"
value={address}
name="address"
onChange={this.handleInputChange}
/>
<br />
<label>phone</label>
<input
type="text"
value={phone}
name="phone"
onChange={this.handleInputChange}
/>
<br />
<label>email</label>
<input
type="text"
value={email}
name="email"
onChange={this.handleInputChange}
/>
<br />
<label>id</label>
<input
type="text"
value={id}
name="id"
onChange={this.handleInputChange}
/>
<button type="button" onClick={this.handleSubmit}>
Submit
</button>
<hr />
{
JSON.stringify(this.state)
}
</div>
);
}
}
export default App;
The ID isn't created until the next render because the component's state isn't initialized when it gets created. You need to initialize its state.
Either in a class constructor
constructor() {
super();
this.state = {
id: new Date().getTime()
}
}
or a state attribute
state = {
id: new Date().getTime()
}
Here is a working codepen example

React JS : Unable to capture the edited value

I am new to React JS. I am trying to capture the edited value from formcontrol in handle change and assign it to a state object and later retrieve assign it to a variable to pass it as a part of the query string to an API for updating the field, handle change is the function called from form-control to assign the edited value to a state object. I am unable to do so; please provide your inputs. Your help is much appreciated. I would like to follow the same for other fields too.
import React, { PropTypes, Component } from 'react';
import {
Panel,
Button,
PageHeader,
ControlLabel,
FormControl,
Pagination,
Form,
Accordion,
Col,
Radio,
FormGroup
} from 'react-bootstrap';
import StatWidget from '../../src/components/Widget';
import CRUDTable,
{
Fields,
Field,
CreateForm,
UpdateForm,
DeleteForm,
} from 'react-crud-table';
const DescriptionRenderer = ({ field }) => <textarea {...field} />;
const styles = {
container: { margin: 'auto', width: 'fit-content' },
};
class displayDetails extends Component {
constructor (props) {
super(props);
this.state = {
updatecustomer: [],
delcustomer: [],
field1 = '',
};
this.handleUpdate = this.handleUpdate.bind(this);
this.handleDelete = this.handleDelete.bind(this);
this.handleCreate = this.handleCreate.bind(this);
this.handleChange = this.handleChange.bind(this);
};
handleChange (e) {
this.state.field1 = e.target.value; // This isn't happening
}
render() {
firstName=this.props.respData.FIELD1;
lastName=this.props.respData.FIELD2;
return (
<div>
<br></br>
<div className="col-lg-3 col-md-6">
<StatWidget
style="panel-primary"
icon="fa fa-dollar fa-5x"
count={this.props.respData.FIELD1}
headerText="FIELD1"
linkTo=""
/>
</div>
<div className="col-lg-3 col-md-6">
<StatWidget
style="panel-green"
icon="fa fa-phone fa-5x"
count={this.props.respData.FIELD2}
headerText="FIELD2"
linkTo=""
/>
</div>
<div className="col-lg-3 col-md-6">
<StatWidget
style="panel-yellow"
icon="fa fa-home fa-5x"
count={this.props.respData.FIELD3}
headerText="FIELD3"
linkTo=""
/>
</div>
<div className="col-lg-3 col-md-6">
<StatWidget
style="panel-red"
icon="fa fa-shopping-bag fa-5x"
count={this.props.respData.FIELD4}
headerText="FIELD4"
linkTo=""
/>
</div>
<div>
<tr>
<td><h1>{this.props.respData.FIELD1} {this.props.respData.FIELD2}</h1></td>
</tr>
</div>
<div>
<table>
<tr>
<td>
<FormGroup style={spacing}>
<ControlLabel>FIELD 1</ControlLabel>
<FormControl onChange={((e) => this.handleChange(this.props.respData.FIELD1))}
value={this.props.respData.FIELD1}
id="field1" name="field1"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
</tr>
<br></br>
</table>
</div>
<br></br>
</div>
)
}
}
export default displayDetails;
Modifying the state directly will not work. The only place you should be setting it directly, is to assign the initial state in your constructor. Everywhere else, you need to use this.setState, to notify your component to recheck the state for a possible rerender:
handleChange(e){
this.setState({
field1: e.target.value
});
}
I believe you are in need of the setState() lifecycle method.
handleChange(e){
this.state.field1 = e.target.value; // This isn't happening
this.setState({
field1: e.target.value
}); // this will update state and trigger rerender
}
class displayDetails extends Component {
constructor(props) {
super(props);
this.state = {
state1: [],
state2: [],
state3: '',
state4: '',
state5: '',
state6: '',
state7: '',
state8: '',
state9: '',
state10: '',
};
this.handleState1change = this.handleState1change.bind(this);
this.handleState2change = this.handleState2change.bind(this);
this.handleState3change = this.handleState3change.bind(this);
this.handleState4change = this.handleState4change.bind(this);
field1=this.props.respData.FIELD1;
this.setState({state3:field1});
};
handlestate1change (e) {
console.log('Inside handle state1 Change',e);
this.setState({state3:e.target.value});
console.log('state1 in handlestate1change',this.state.state3);
}
componentWillReceiveProps(){
this.setState({state3:field1});
console.log('newfirstName in Component will mount',this.state.state3);
}
render() {
return(
<td>
<FormGroup style={spacing}>
<ControlLabel>Field1</ControlLabel>
<FormControl onChange={this.handleState1change}
value={this.state.state3}
id="field1" name="field1"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
);
}
}
}

redux-form how to load data for editing

I am working with redux-form and it seems confusing me to load initial data for edit form but the data is not being validated on submit. I have managed to pass and load data into the fields but that seems not loading into the form props etc. Please see the following piece of code and let me know if need something more.
Form_Bayan.js
import React, {Component, PropTypes} from "react";
import {browserHistory} from "react-router";
import {reduxForm, Field} from "redux-form";
import {MyCustomInput, MySimpleInput, MyCustomSelect} from "./__form_field_components";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import {
ADMIN_FETCH_AUTOSUGGESTS_Lbl,
adminFetchAutoSuggestCats_act,
ADMIN_GETCATID_BYNAME_Lbl,
adminGetCatIdByName_act,
ADMIN_ADDNEWBAYAAN_Lbl,
adminAddNewBayaan_act,
adminFetchArticlesByCat_act,
adminUpdateBayaan_act
} from "../../actions/adminActionCreators";
import _ from "lodash";
class NewBayanForm extends Component {
constructor(props) {
super(props);
this.state = {
submitButtonMeta: {
btnTitle: "Save",
btnClass: "btn btn-default",
btnIcon: null,
disabled: false
},
globalMessage: { // set when an action is performed by ActionCreation+Reducer and a message is returned
message: "",
className: ""
},
tempData: {
the_bayaansMainCat_id: this.props.associatedMainCatId, // being passed from parent component to avoide redundent declaration
the_autoSuggestCatList: [],
slug: "",
the_catId: null
}
};
}
resetMessageState() {
var noMsg = {message: "", className: ""};
this.setState({globalMessage: noMsg});
}
componentDidMount() {
this.props.adminFetchAutoSuggestCats_act(this.state.tempData.the_bayaansMainCat_id);
}
doSubmit(props) {
var newBayanObj = {
item_title: props.titleTxt,
item_slug: this.state.tempData.slug,
content: props.videoIdTxt,
picture: "",
attachment: "",
media_path: "https://www.youtube.com/watch?v=" + props.videoIdTxt,
reference: "",
tag_keywords: props.keywordsTxt,
author_name: props.authorTxt,
cat_id: this.state.tempData.the_catId
};
this.props.adminUpdateBayaan_act(newBayaanObj)
.then(() => {
this.props.adminFetchArticlesByCat_act(this.props.associatedMainCatId)
.then(() => {
this.props.toggleViewFunction(); // comming from Parent Class (bayaansPage)
});
});
}
fetchCategoryId(value) {
// make API call to fetch / generate category ID for this post
this.props.adminGetCatIdByName_act(value, this.state.tempData.the_bayaansMainCat_id); // '1': refers to look up under 'Bayaans' parent category for the specified category name
}
// will always receive and triggers when there are 'new props' and not old/same props
render() { // rendering Edit form
const {handleSubmit} = this.props;
console.log('<NewBayanForm> (render_editForm) this.props:', this.props);
return (
<div className="adminForm">
<form onSubmit={handleSubmit(this.doSubmit.bind(this))}>
<div className="col-sm-6">
<div className="row">
<div className="col-sm-5"><label>Title:</label></div>
<div className="col-sm-7"><Field name="titleTxt" component={MySimpleInput}
defaultValue={this.props.name} type="text"
placeholder="Enter Title"/></div>
</div>
<div className="row">
<div className="col-sm-5"><label>Slug:</label></div>
<div className="col-sm-7">{this.state.tempData.slug || this.props.slug} <input
type="hidden" name="slugTxt" value={this.state.tempData.slug}/></div>
</div>
<div className="row">
<div className="col-sm-5"><label>Select Category:</label></div>
<div className="col-sm-7"><Field name="catTxt" component={MyCustomSelect}
defaultValue={this.props.category_name} type="text"
placeholder="Select or Type a New"
selectableOptionsList={this.state.tempData.the_autoSuggestCatList}
onSelectionDone={ this.fetchCategoryId.bind(this) }/>
<input type="hidden" name="catIdTxt"
value={this.state.tempData.the_catId || this.props.category_id}/>
</div>
</div>
</div>
<div className="col-sm-6">
<div className="row">
<div className="col-sm-5"><label>Youtube Video ID:</label></div>
<div className="col-sm-7"><Field name="videoIdTxt" component={MySimpleInput}
defaultValue={this.props.content} type="text"
placeholder="TsQs9aDKwrw"/></div>
<div className="col-sm-12 hint"><b>Hint: </b> https://www.youtube.com/watch?v=<span
className="highlight">TsQs9aDKwrw</span></div>
</div>
<div className="row">
<div className="col-sm-5"><label>Author/Speaker:</label></div>
<div className="col-sm-7"><Field name="authorTxt" component={MySimpleInput}
defaultValue={this.props.author} type="text"/></div>
</div>
<div className="row">
<div className="col-sm-5"><label>Tags/Keywords:</label></div>
<div className="col-sm-7"><Field name="keywordsTxt" component={MySimpleInput}
defaultValue={this.props.tag_keywords} type="text"/>
</div>
</div>
</div>
<div className="row">
<div className={this.state.globalMessage.className}>{this.state.globalMessage.message}</div>
</div>
<div className="buttonControls">
<a className="cancelBtn" onClick={this.props.toggleViewFunction}>Cancel</a>
<button className={this.state.submitButtonMeta.btnClass}
disabled={this.state.submitButtonMeta.disabled}>
{this.state.submitButtonMeta.btnTitle}</button>
</div>
</form>
</div>
);
}
}
function validate(values) { // Validate function being called on Blur
const errors = {};
if (!values.titleTxt)
errors.titleTxt = "Enter Title";
if (!values.catTxt)
errors.catTxt = "Select/Enter a Category";
if (!values.videoIdTxt)
errors.videoIdTxt = "Enter youtube video ID (follow the provided hint)";
if (!values.keywordsTxt)
errors.keywordsTxt = "Enter keywords (will help in search)";
return errors;
}
// ReduxForm decorator
const newBayanFormAdmin_reduxformObj = reduxForm({
form: "newBayanFormAdmin", // any unique name of our form
validate // totally equivelent to--> validate: validate
});
function mapStateToProps({siteEssentials}, ownProps) {
// 1st param is related to our Redux State, 2nd param relates to our own component props
var initialValues = {
titleTxt: ownProps.name,
slugTxt: ownProps.slug,
catTxt: ownProps.category_name,
catIdTxt: ownProps.category_id,
videoIdTxt: ownProps.content,
authorTxt: ownProps.author,
keywordsTxt: ownProps.tag_keywords
};
return ({siteEssentials}, initialValues);
};
function mapDispatchToProps(dispatch) {
return bindActionCreators({
adminFetchAutoSuggestCats_act,
adminGetCatIdByName_act,
adminAddNewBayaan_act,
adminFetchArticlesByCat_act
}, dispatch);
};
NewBayanForm = connect(mapStateToProps, mapDispatchToProps) (newBayanFormAdmin_reduxformObj(NewBayanForm));
export default NewBayanForm;
try initialValues for more details
inside reduxform :
export default NewBayanForm = reduxForm({ form: 'NewBayanForm', initialValues: {
name: "abc",
email: "abc#gmail.com",
phoneNo: "1234567890"
} })(NewBayanForm)
or
<NewBayanForm initialValues={yourObject} />
I found this tutorial which is quite simple and helpful.
https://www.davidmeents.com/?p=38

"user.profile" undefined despite its declaration in Accounts.createUser()

I am working on a "settings" page where a logged in user can change their profile picture. However it seems that Meteor is having trouble finding the profile attribute for a user.
signup.js (here is where I create the user on signup and create the profile attribute)
import React, { Component } from 'react';
import { browserHistory } from 'react-router';
export default class Signup extends Component {
handleSubmit(event) {
event.preventDefault();
var signupEmail = event.target.signupEmail.value;
var signupPassword = event.target.signupPassword.value;
if (signupPassword !== '') {
Accounts.createUser({
email: signupEmail,
password: signupPassword,
profile: {
avatar: "/user-default.svg"
}
}, (err) => {
err ? (console.log(err.reason)) : browserHistory.push("/app/profile");
});
}
}
render() {
return (
<div className="login-form">
<form onSubmit={this.handleSubmit}>
<div className="input-options">
<input type="text" placeholder="Email" name="signupEmail" />
</div>
<div className="input-options">
<input type="password" placeholder="Password" name="signupPassword" />
</div>
<button className="login-submit bold">Sign me up!</button>
</form>
</div>
);
}
}
profile_settings.js
import React, { Component } from 'react';
import { Link } from 'react-router';
import reactMixin from 'react-mixin';
import ReactMeteorData from 'meteor/react-meteor-data';
export default class ProfileSettings extends Component {
constructor(props) {
super(props);
this.state = {
avatar: this.props.user.profile.avatar
}
}
getMeteorData(){
return{
user: Meteor.user()
}
}
componentWillMount(){
// we create this rule both on client and server
Slingshot.fileRestrictions("avatar", {
allowedFileTypes: ["image/png", "image/jpeg", "image/gif"],
maxSize: 2 * 500 * 500
});
}
upload(){
var userId = Meteor.user()._id;
var metaContext = {avatarId: userId};
var uploader = new Slingshot.Upload("UsersAvatar", metaContext);
uploader.send(document.getElementById('input').files[0], function (error, downloadUrl) { // you can use refs if you like
if (error) {
// Log service detailed response
console.error('Error uploading', uploader.xhr.response);
alert (error); // you may want to fancy this up when you're ready instead of a popup.
}
else {
// we use $set because the user can change their avatar so it overwrites the url :)
Meteor.users.update(Meteor.userId(), {$set: {"profile.avatar": downloadUrl}});
}
// you will need this in the event the user hit the update button because it will remove the avatar url
this.setState({avatar: downloadUrl});
}.bind(this));
}
formSubmit(){
let avatarUrl = this.state.avatar;
Meteor.users.update( {_id: Meteor.userId() }, {
$set: {profile: avatarUrl}
});
}
render() {
return (
<div>
<div className="sticky-header">
<h3>Settings</h3>
</div>
<form>
<div className="row well">
<div className="col-md-6">
<div className="form-group">
<label htmlFor="exampleInputFile">File input</label>
<input type="file" id="input" onChange={this.upload.bind(this)} />
<p className="help-block">Image max restriction: 2MB, 500x500. Cropped: 200x200</p>
</div>
</div>
<div className="col-md-6 utar-r">
<img src={this.state.avatar} height="200" width="200" alt="..." className="img-rounded" />
</div>
<div className="form-group">
<button className="btn btn-lg btn-primary btn-block" type="submit" onClick={this.formSubmit.bind(this)}>Update Profile</button>
</div>
</div>
</form>
<footer className="sticky-footer">
<Link to="/app/profile">
<button className="profile-edit bg-black">
<h3>Cancel</h3>
</button>
</Link>
<Link to="">
<button className="profile-edit">
<h3>Save Changes</h3>
</button>
</Link>
</footer>
</div>
);
}
}
reactMixin(ProfileSettings.prototype, ReactMeteorData);
Here is the error I am getting: TypeError: Cannot read property 'profile' of undefined
The error is not failing to find an profile attribute, but says that there's no user (or that user is undefined) This is exactly what TypeError: Cannot read property 'profile' of undefined means.
There are a few errors in your code:
the return of getMeteorData is available under this.data and not this.props
getMeteorData will run after constructor so there's no way to get Meteor's data in the constructor
getMeteorData returns data reactively, and is likely not to have the data you want when you instantiate the class anyway
So I'd recommend using the container/component approach that is like:
export default class ProfileSettingsContainer extends Component {
getMeteorData(){
return{
user: Meteor.user()
}
}
render() {
const user = this.data.user;
if (user) {
return <ProfileSettings user={user} />
} else {
return null; // or what ever placeholder you want while the data is being loaded
}
}
}
class ProfileSettings extends Component {
constructor(props) {
super(props);
this.state = {
avatar: props.user.profile.avatar
}
}
}
with this structure, the ProfileSettings will instantiate with something under props.user
Finnaly,
Meteor.users.update( {_id: Meteor.userId() }, {
$set: {profile: avatarUrl}
});
should be
Meteor.users.update( {_id: Meteor.userId() }, {
$set: {'profile.avatar': avatarUrl}
});
but that's unrelated

Categories