var myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
myHeaders.get('Content-Type') // should return 'text/xml'
export function httpGet(url) {
return fetch(url, {
headers: buildHeaders(),
})
.then(checkStatus)
}
function buildHeaders() {
const authToken = localStorage.getItem('myapp.token')
return { ...defaultHeaders, Authorization: authToken }
}
const defaultHeaders = {
Accept: 'application/json',
'Content-Type': 'application/json',
}
loadData() {
if (state.data.length) {
// ничего не делай
} else {
this.props.callActionAndLoadData()
}
}
export function myAction(date) {
return {
type: 'CHANGE_DATE',
data: date
}
}
const mapStateToProps = (state) => ({
dates: state.dates,
})
const mapDispatchToProps = (dispatch) => ({
myAction: (date) => dispatch(myAction(date)),
})
<DayPickerSection selected={this.props.dates.current} myAction={this.props.myAction} />
const DayPickerSection = ({selected, myAction}) => {
return (
<div>
<DatePicker selected={selected}
onChange={(date) => myAction(date) }/>
</div>
);
};
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { myAction } from '../actions'
class App extends Component {
render() {
const { dates, myAction } = this.props
return (
<div className='my-app'>
<DayPickerSection selected={dates.current} myAction={myAction} />
</div>
)
}
}
const mapStateToProps = (state) => ({
dates: state.dates,
})
const mapDispatchToProps = (dispatch) => ({
myAction: (date) => dispatch(myAction(date)),
})
export default connect(mapStateToProps, mapDispatchToProps)(App)
<ВыборДаты текущаяДата={Дата_из_стора/или роута} />
<DatePicker current={myDate} />
<DatePicker onDateChange={this.props.getTickets} />
<ВыборДаты текущая={мояДата} onDateChange={this.props.загрузиБилеты} />
class DayPicker extends Component {
constructor(props) {
super(props)
this.state = {
start: null,
}
}
componentWillMount() {
const { startTime } = this.props
this.setState({ start: startTime })
}
componentWillReceiveProps(nextProps) {
const { startTime } = nextProps
this.setState({ start: startTime })
}
render() {
const { start } = this.state
const { onDateChange } = this.props
return (
<section>
<div className='date-picker'>
<DatePicker
className='form-control'
placeholderText={'Введите дату'}
selected={moment(start)}
onChange={ (moment) => onDateChange('startTime', moment) }/>
</div>
</section>
)
}
}
// обработчик onDateChange
onDateChange(dateField, moment) {
const query = this.props.location.query
const nextQuery = {
...query,
[dateField]: moment.format('YYYY-MM-DD'),
}
// так как у меня все завязано на роутинге, здесь другой вызов ниже,
// но для простоты примеры, здесь необходимо вызвать экшен, например getTickets(dateField)
}
// это находится в render функции
const { startTime } = this.props
<div className='row row-margin'>
<div className='col-md-12'>
<DayPicker
onDateChange={this.onDateChange}
startTime={startTime}
/>
</div>
</div>
// ваш экшен getTickets(dateField) наверняка подключается так
import { getTickets } from '../../actions/TicketsActions'
//...
const mapDispatchToProps = (dispatch) => ({
getTickets: (dateField) => dispatch(getUsers(dateField)),
})
//...
// ваша переменная startTime наверняка приходит из редьюсера / роута, у меня из роута
const mapStateToProps = (state, ownProps) => ({
startTime: ownProps.location.query.startTime,
})
NODE_ENV=production webpack --progress --config ./webpack.prod.config.js -p
...
render()
...
if (this.props.isFetching) {
<p> Loading...</p>
} else {
<p> {ВАШИ_ДАННЫЕ} </p>
}
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'hbs'); //в офф.доке используют расширение handlebars
кажется, что не использовал это все на 100%
Как на счет jwt ?
const express = require('express')
const router = express.Router()
const User = require('../models/user')
const v4 = require('node-uuid').v4
const jwt = require('jsonwebtoken')
router.post('/signup', (req, res, next) => {
req.check('email', 'Please enter a valid email').len(1).isEmail()
req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
const errors = req.validationErrors()
if (errors) {
return res.status(400).json({ errors })
} else {
User.hashPassword(req.body.password, (err, passwordHash) => {
if (err) {
return res.status(400).json({ error: err.message })
}
const user = new User({
name: req.body.name,
nickname: req.body.nickname,
email: req.body.email,
password: req.body.password,
})
user.passwordHash = passwordHash
user.save((err, item) => {
if (err) {
return res.status(400).json({ error: err.message })
}
const payload = {
_id: item._id,
iss: 'http://localhost:3000',
permissions: 'poll',
}
const options = {
expiresIn: '7d',
jwtid: v4(),
}
const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
jwt.sign(payload, secret, options, (err, token) => {
return res.json({ data: token })
})
})
})
}
})
router.post('/signin', (req, res, next) => {
req.check('email', 'Please enter a valid email').len(1).isEmail()
req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
const errors = req.validationErrors()
const password = req.body.password
if (errors) {
return res.status(400).json({ errors })
} else {
User.findOne({ email: req.body.email }, (err, user) => {
if (err) {
return res.status(400).json({ error: err.message })
}
if (!user) {
return res.status(400).json({ error: 'User not found' })
}
User.comparePasswordAndHash(password, user.passwordHash, (err, areEqual) => {
if (err) {
return res.status(400).json({ error: err.message })
}
if (!areEqual) {
return res.status(400).json({ error: 'Wrong password' })
}
const payload = {
_id: user._id,
iss: 'http://localhost:3000',
permissions: 'poll',
}
const options = {
expiresIn: '7d',
jwtid: v4(),
}
const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
jwt.sign(payload, secret, options, (err, token) => {
return res.json({ data: token })
})
})
})
}
})
module.exports = router;
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const Schema = mongoose.Schema
let bcrypt_cost = 12
const userSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true },
passwordHash: String,
})
userSchema.statics.hashPassword = (passwordRaw, cb) => {
if (process.env.NODE_ENV === 'test') {
bcrypt_cost = 1
}
bcrypt.hash(passwordRaw, bcrypt_cost, cb)
}
userSchema.statics.comparePasswordAndHash = (password, passwordHash, cb) => {
bcrypt.compare(password, passwordHash, cb)
}
const User = mongoose.model('User', userSchema)
module.exports = User
onClick={this.updateClick('params')}
- что вы ожидаете от такой записи? Давайте поразмышляем: в onClick вы должны передать функцию-обработчик, а вы передаете РЕЗУЛЬТАТ функции this.updateClick так как вызываете ее с ( )