0

Alright, this is going to be a little long. I'm somewhat new to React & Redux. So I have a React & Redux front-end, with a Node & Express backend as well as mySQL for the DB.

I'm building part of a web portal, where users can create jobs. The job creation part is working fine, but I'm having trouble with retrieving data from the DB(GET request).

Here's the structure:

There's a postJobs.js parent, which has several child components:

  1. CreateJob
  2. AddMoreDetails
  3. AllocateBudget

All of these child components are tabs which are triggered through clicking the tabs.

When the job is created through the CreateJob component, a jobID is generated in the DB(primary key) which is then sent to the Redux Store.

I'm using the same component, i.e. CreateJob for both adding a job and updating the job to prevent duplication.

When the user successfully creates a job, he/she's navigated to the second tab(AddMoreDetails).

I've defined an action for getting the created jobs from the db, and the action takes jobID as a parameter(the jobID is retrieved from the Redux store and passed to the action).

But I get "job_id is undefined" in my Node backend. I've realized that it's not getting the jobId from req.body, but I'm unable to figure out an alternative as to how to send the jobID from the frontend to the backend.

I've tested the API in Postman and it's working properly.

Here's the error I'm getting and the relevant back-end and front-end code:

Error

Unhandled rejection TypeError: Cannot read property 'job_id' of 
undefined at jobsDao.getCurrentJob.then.result

Backend

userRouter.js

router.get('/getCreatedJob', postJobController.getCreatedJob);

postJob.js

  let getCreatedJob = (req, res) => {
  let jobId = req.body.jobId;
  let skills = [];
  jobsDao.getCurrentJobSkills(jobId).then(result => {
    result.forEach(skill => {
    skills.push(skill.skill_id);
  });
});
  jobsDao.getCurrentJob(jobId).then(result => {
    console.log(result);
    res.send({
      success: true,
      message: 'Got recent Created Job ',
      jobId: result[0].job_id,
      jobTitle: result[0].job_title,
      jobType: result[0].job_type_id,
      jobSkills: skills
     });
   });
 };

jobsDao.js

   let getCurrentJobSkills = jobId => {
     return Promise.using(getDBConnection(), connection => {
       return connection.query(
         `select skill_id from job_skill where job_id = 
          ${connection.escape(jobId)}`
      );
    });
   };

  let getCurrentJob = jobId => {
    return Promise.using(getDBConnection(), connection => {
      return connection.query(
        `select job_id,job_title,job_type_id from job where job_id 
         = ${connection.escape(jobId)}`
     );
   });
  };

Front-End

apiConfig.js

export default {
   getCreatedJob: {
   url: '/api/secured/client/getCreatedJob',
   method: 'GET',
   data: {
     jobId: ''
   },
   showResultMessage: false,
   showErrorMessage: true
   }
   // Other API calls here
}

postJobAction.js

export const actionGetCreatedJob = data => {
  const request = apiService('getCreatedJob', data);
  return {
    type: GET_CREATED_JOB,
    payload: request
  };
};

reducerPostJob.js

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case GET_CREATED_JOB:
      console.log(action.payload.data);
      return { ...state };
    // Other cases here
    default:
    return state;
  }

}

createJob.js

componentDidMount() {
  const jobId = this.props.clientPostJob.jobId;
  console.log(jobId); // The createdJob is is being logged here 
                         correctly
  if (jobId) {
    this.props.actionGetCreatedJob({jobId})
    .then(() => {
      this.props.actionLoaderHide()
      /* Add logic here for populating the form fields with the 
        data retrieved from db */
    })
      .catch(err => console.log(err));
  }
}

const mapStateToProps = state => {
  return {
  clientPostJob: state.clientPostJob,
  userInfo: state.userInfo.userData,
  jobId: state.clientPostJob.jobId
 };
};

const mapDispatchToProps = dispatch => {
 return bindActionCreators({
     actionLoaderHide,
     actionLoaderShow,
     actionGetCreatedJob,
  },
  dispatch
  );
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CreateJob);

What would be the best approach of sending the jobID to the backend?

  • If you create the job I think you shouldn't use ```GET```, maybe you should change your implementation to use ```POST``` in order to create/update the job. What library do you use to sent HTTP requests? – Maciej Trojniarz Sep 02 '19 at 08:56
  • I've used POST to create the job and PUT to update the job. I'm using GET to fetch the job I've created. I'm using axios for HTTP requests. – Vishwanath Sastry Sep 02 '19 at 11:14

1 Answers1

2

I personally would use jobId as a parameter in the path (/api/secured/client/getCreatedJob/<jobId>). Your code suggest that you are trying to sent it inside body.

1) Send body in method GET axios

2) HTTP GET with request body

Maciej Trojniarz
  • 654
  • 4
  • 13