I have banged around in this for a while now. Looked at this question but its not quite what I want.
In a nutshell... I have const expression = to a function that is chained to another function that makes an API call in a separate file to LoginContainer but in the same folder -(its called reducer.js but has the actions as well at this stage). If successful it receives a token which it saves in local storage. this works fine.
Here it is.
import { fetch, addTask } from 'domain-task'
import { saveJwt, clearJwt } from '../auth/jwt'
import { handleErrors } from '../utils/http'
const REQUEST_LOGIN_TOKEN = 'REQUEST_LOGIN_TOKEN'
const RECEIVE_LOGIN_TOKEN = 'RECEIVE_LOGIN_TOKEN'
const ERROR_LOGIN_TOKEN = 'ERROR_LOGIN_TOKEN'
const REQUEST_USER = 'REQUEST_USER'
const RECEIVE_USER = 'RECEIVE_USER'
const ERROR_USER = 'ERROR_USER'
// ******************* action
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
})
.catch(error => {
clearJwt()
dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
})
addTask(task)
return task
}
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Login from './Login'
import { requestLoginToken } from './reducer'
class LoginContainer extends Component {
static contextTypes = {
router: PropTypes.object.isRequired
}
componentWillReceiveProps(nextProps) {
if (nextProps.isAuthorised) {
this.context.router.push('/')
}
}
submit = (values) => {
console.log('got values!', values)
this.props.requestLoginToken(values.username, values.password)
}
render() {
return (
<Login onSubmit={this.submit} />
)
}
}
const mapStateToProps = (state) => ({
isAuthorised: state.login.isAuthorised,
})
const mapDispatchToProps = (dispatch) => ({
requestLoginToken: (username, password) => dispatch(requestLoginToken(username, password)),
//requestSelectData: (values = {}) => dispatch(requestSelectData(values = {})),
})
export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer)
In the loginContainer (above), Once the "userName" and "password" have been entered and the submit button clicked, the expression "requestLoginToken" is called.
My Problem
I want to fetch a significant amount of data based on the above expression "requestLoginToken" successfully saving a JWT token into local storage. It does this successfully now with the right username and password.
I know I can't make another call from within the expression "requestLoginToken" using a ".then" as it specifically needs to retrieve and then save a token first - I have to wait till it finishes to know if I have a token. I need to run a second expression that only gets run if this promise is successful ie via a conditional statement. "If (JWT) etc"
1) Could someone tell me where and how I add this conditional statement. Im thinking its in the Logincontainer in the submit? ..how do would I structure the condition?
2) Where and how do I add the const = function for the retrieval of the data eg if I place it in another separate file do I still or even need to register it in mapDispatchToProps in the loginContainer etc
EDIT
Taking Nate Kimball's answer and running with it. Decided to split it out into its own "const" called "selectData" which I plan to call right underneath the line "saveJwt(data)".
However I find I am now getting an error:
Unexpected Token , expected
Its on the very last line of the following code block below.. (right curly bracket has red under it) checked it for sytax but cant workout why.
I think the approach is correct though.
const selectData = () => {
dispatch({ type: REQUEST_SELECT_DATA })
const token = jwt.access_token
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const selectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers,
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: data })
.catch(error => {
clearJwt()
dispatch({ type: ERROR_SELECT_DATA, payload: error.message })
})
}
}