I have a redux-form which is used to receive data from the user and post it to a back-end API server.While posting data to the server,I want to generate a unique id for each set of data that is being posted to the server, so that I can use the id later for referencing that particular set and displaying it to the user.So,how to generate that unique id automatically while posting a set of data to the server?
The code for my redux-form is given below:
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { createPosts } from '../actions/posts_action';
class CreatePost extends Component {
constructor() {
super();
this.state = {
selectValue : ''
};
this.handleChange = this.handleChange.bind(this);
this.renderCategory = this.renderCategory.bind(this);
}
renderField(field) {
return(
<div className="title-design">
<label className="label-design"> {field.label} </label>
<input
type="text"
className="title-input"
{...field.input}
/>
<div className="text-help has-danger">
{field.meta.touched ? field.meta.error : ''}
</div>
</div>
);
}
handleChange(e) {
const value=e.target.value;
this.props.change("categories",value);
this.setState({selectValue: value}, () => {
console.log(value)
});
}
renderCategory(field) {
return(
<div className="title-design">
<label className="label-design">{field.label} </label>
<Field name="category" className="title-input" component="select">
<option></option>
<option value="react">React</option>
<option value="redux">Redux</option>
<option value="udacity">Udacity</option>
</Field>
<div className="text-help has-danger">
{field.meta.touched ? field.meta.error : ''}
</div>
</div>
);
}
onSubmit(values) {
this.props.createPosts(values, () => {
this.props.history.push('/');
});
}
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title for Post"
name="title"
component={this.renderField}
/>
<Field
label="Post Content"
name="body"
component={this.renderField}
/>
<Field
label="Category"
name="category"
component={this.renderCategory}
/>
<button type="submit" className="btn btn-primary">Submit</button>
<Link to="/">
<button className="cancel-button">Cancel</button>
</Link>
</form>
);
}
}
function validate(values) {
const errors = {} ;
if (!values.title) {
errors.title = "Enter a title";
}
if (!values.body) {
errors.body = "Enter some content";
}
if(!values.category) {
errors.category = "Please select a category";
}
if (!values.id) {
errors.id = "ID not generated";
}
return errors;
}
export default reduxForm({
validate : validate, //validate
form : 'CreatePostForm'
})(
connect(null,{ createPosts })(CreatePost)
);
The action creator for creating a new post is given below:
//Action Creator for creating posts
export function createPosts(values, callback) {
return dispatch => {
return axios.post(`${API}/posts`,values,{headers})
.then((data) => {
callback();
console.log(data)
dispatch({
type: CREATE_POST,
payload: data
})
})
}
}
Reducer for creating the post:
import _ from 'lodash';
import { FETCH_POSTS, FETCH_POST, CREATE_POST } from '../actions/posts_action';
export default function(state = {}, action) {
switch (action.type) {
case FETCH_POST:
// const post = action.payload.data;
// const newState = { ...state, };
// newState[post.id] = post;
// return newState;
return {...state, [action.payload.id]: action.payload};
case FETCH_POSTS:
return {posts: { ...state.posts, ...action.payload }};
case CREATE_POST:
return {posts: { ...state, ...action.payload}};
default:
return state;
}
}
So,how to genrate the id for each set of data that is sent to the server?
Edit 1:
I am trying to add the uuid on my onSubmit() method as shown below,but it doesn't work.I sit not how it should be done or I have to do it some other way?
onSubmit(values) {
this.props.createPosts(values, () => {
uuidv1();
this.props.history.push('/');
});
}
Edit 2:
Sever file for posts:
const clone = require('clone')
let db = {}
const defaultData = {
"8xf0y6ziyjabvozdd253nd": {
id: '8xf0y6ziyjabvozdd253nd',
timestamp: 1467166872634,
title: 'Udacity is the best place to learn React',
body: 'Everyone says so after all.',
author: 'thingtwo',
category: 'react',
voteScore: 6,
deleted: false,
commentCount: 2
},
"6ni6ok3ym7mf1p33lnez": {
id: '6ni6ok3ym7mf1p33lnez',
timestamp: 1468479767190,
title: 'Learn Redux in 10 minutes!',
body: 'Just kidding. It takes more than 10 minutes to learn technology.',
author: 'thingone',
category: 'redux',
voteScore: -5,
deleted: false,
commentCount: 0
}
}
function getData (token) {
let data = db[token]
if (data == null) {
data = db[token] = clone(defaultData)
}
return data
}
function getByCategory (token, category) {
return new Promise((res) => {
let posts = getData(token)
let keys = Object.keys(posts)
let filtered_keys = keys.filter(key => posts[key].category === category && !posts[key].deleted)
res(filtered_keys.map(key => posts[key]))
})
}
function get (token, id) {
return new Promise((res) => {
const posts = getData(token)
res(
posts[id].deleted
? {}
: posts[id]
)
})
}
function getAll (token) {
return new Promise((res) => {
const posts = getData(token)
let keys = Object.keys(posts)
let filtered_keys = keys.filter(key => !posts[key].deleted)
res(filtered_keys.map(key => posts[key]))
})
}
function add (token, post) {
return new Promise((res) => {
let posts = getData(token)
posts[post.id] = {
id: post.id,
timestamp: post.timestamp,
title: post.title,
body: post.body,
author: post.author,
category: post.category,
voteScore: 1,
deleted: false,
commentCount: 0
}
res(posts[post.id])
})
}
function vote (token, id, option) {
return new Promise((res) => {
let posts = getData(token)
post = posts[id]
switch(option) {
case "upVote":
post.voteScore = post.voteScore + 1
break
case "downVote":
post.voteScore = post.voteScore - 1
break
default:
console.log(`posts.vote received incorrect parameter: ${option}`)
}
res(post)
})
}
function disable (token, id) {
return new Promise((res) => {
let posts = getData(token)
posts[id].deleted = true
res(posts[id])
})
}
function edit (token, id, post) {
return new Promise((res) => {
let posts = getData(token)
for (prop in post) {
posts[id][prop] = post[prop]
}
res(posts[id])
})
}
function incrementCommentCounter(token, id, count) {
const data = getData(token)
if (data[id]) {
data[id].commentCount += count
}
}
module.exports = {
get,
getAll,
getByCategory,
add,
vote,
disable,
edit,
getAll,
incrementCommentCounter
}
First, you import React and Axios so that both can be used in the component. Then you hook into the componentDidMount lifecycle hook and perform a GET request. You use axios. get(url) with a URL from an API endpoint to get a promise which returns a response object.
Well, normally you'd let the server generate that id, then send it back down as part of the response for the axios call, but if you really want to generate an ID on a client, I suggest using uuid and one of it's various UUID generators: https://www.npmjs.com/package/uuid
example from the docs:
const uuidv4 = require('uuid/v4');
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
You've added more code, and I think you're better served using uuidv4() on your server; something like:
function add (token, post) {
return new Promise((res) => {
let posts = getData(token)
let id = uuidv4();
posts[id] = {
id: id,
timestamp: post.timestamp,
title: post.title,
body: post.body,
author: post.author,
category: post.category,
voteScore: 1,
deleted: false,
commentCount: 0
}
res(posts[id])
})
}
This way, the id is generated on the server. The client no longer needs depend on uuid, and you're not "trusting" the client to generate a valid id. The id would render back to the client as part of the response, and you could then use it from the client when doing edits, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With