Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a unique id automatically for the data that is posted to an API server using axios library in redux

Tags:

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
}
like image 695
pranami Avatar asked Dec 30 '17 05:12

pranami


People also ask

How integrate post API in React JS using Axios?

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.


1 Answers

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.

like image 166
billjamesdev Avatar answered Sep 19 '22 12:09

billjamesdev