I've got a problem that I've been working on now for a few days now and can't find the solution. I created an API with Lumen and a frontend with ReactJS. This all works fine with a GET request, but it fails when I send a POST request. For some strange reasons the requests works when I send it with Postman. Now some Code!
First of all the JS-Script that sends the request:
import moment from 'moment';
import React, {Component} from 'react';
import { Modal, Form, Button, Input, DatePicker, Select, message } from 'antd';
const {RangePicker} = DatePicker;
const FormItem = Form.Item;
const Option = Select.Option;
const api_url = 'api/v1/';
class NewEventForm extends React.Component {
constructor(props) {
super(props);
this.state = {
confirmLoading: false,
categories: []
};
this.onCreate = this.onCreate.bind(this);
this.onCancel = this.onCancel.bind(this);
}
componentDidMount() {
fetch(api_url + 'category')
.then(results => {
return results.json();
}).then(data => {
let categories = data.map((cat) => {
return (
<Option key={cat.id} value={cat.id}>{cat.name}</Option>
);
});
this.setState({categories: categories});
});
}
updateStates() {
this.props.updateState();
this.setState({confirmLoading: false});
}
onCreate() {
this.props.form.validateFields((err, values) => {
this.setState({
confirmLoading: true
});
if (err) {
this.setState({
confirmLoading: false
});
return;
}
let event = {
title: values.title,
description: values.description,
start_time: values.date[0],
end_time: values.date[1],
category_id: values.category
};
fetch(api_url + 'event', {
method: 'POST',
/* headers are important*/
headers: {
"content-type":"application/json",
"cache-control":"no-cache",
"accept":"*/*",
},
body: JSON.stringify(event)
}).then(response => {
if(response.ok) {
return response.json();
}
throw new Error("Antwort der API war nicht 'Ok'!");
}).then(data =>{
this.updateStates();
message.success('Das Ereignis wurde erfolgreich eingetragen!');
}).catch(error => {
//console.log(error);
this.updateStates();
message.error('Das Ereignis wurde nicht erstellt. Bitte versuche es später nochmal!');
});
});
}
onCancel(e) {
e.preventDefault();
this.updateStates();
}
render() {
const {getFieldDecorator, getFieldError} = this.props.form;
return(
<Modal title="Neue Veranstaltung hinzufügen" okText="Eintragen" confirmLoading={this.state.confirmLoading} visible={this.props.visible} onOk={this.onCreate} onCancel={this.onCancel}>
<Form layout="vertical">
<FormItem label="Titel">
{getFieldDecorator('title', {
rules: [{required: true, message: 'Bitte einen Titel angeben!' }],
})(
<Input />
)}
</FormItem>
<FormItem label="Beschreibung">
{getFieldDecorator('description')(<Input type="textarea" />)}
</FormItem>
<FormItem label="Kategorie">
{getFieldDecorator('category', {
rules: [{required: true, message: 'Bitte einen Kategorie auswählen!' }],
})(
<Select placeholder="Kategorie auswählen...">
{this.state.categories}
</Select>
)}
</FormItem>
<FormItem label="Zeitraum" className="collection-create-formlast-form-item">
{getFieldDecorator('date', {
rules: [{required: true, message: 'Bitte einen Zeitraum auswählen!' }],
})(
<RangePicker
showTime={{
hideDisabledOptions: true,
defaultValue: [moment('00:00', 'HH:mm'), moment('00:00', 'HH:mm')],
format: 'HH:mm'
}}
format="DD.MM.YYYY HH:mm"
/>
)}
</FormItem>
</Form>
</Modal>
);
}
}
export const NewEventModal = Form.create()(NewEventForm);
My database has three models. Event, Category and User: Category.id<---1:n--->Event.category_id||Event.updated_by<---n:1--->User.id
Now the EventController:
<?php
namespace App\Http\Controllers;
use App\Event;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class EventController extends Controller{
public function index(){
$Events = Event::all();
return response()->json($Events);
}
public function getEvent($id){
$Event = Event::with(['category', 'user'])->find($id);
return response()->json($Event);
}
public function createEvent(Request $request){
$User = \App\User::find(1);
$Category = \App\Category::find(1);
$Event = new Event;
$Event->fill($request->all());
$Event->user()->associate($User);
$Event->category()->associate($Category);
$obj = '';
foreach ($request->all() as $key => $value) {
$obj .= '[' . $key . '] => "' . $value . '"; ';
}
\Log::warning('Test: ' . $obj);
$Event->save();
return response()->json($request);
}
public function deleteEvent($id){
$Event = Event::find($id);
$Event->delete();
return response()->json('deleted');
}
public function updateEvent(Request $request,$id){
$Event = Event::find($id);
$Event->title = $request->input('title');
$Event->description = $request->input('description');
$Event->start_time = $request->input('start_time');
$Event->end_time = $request->input('end_time');
$Event->save();
return response()->json($Event);
}
}
And the EventModel:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['title', 'description', 'start_time', 'end_time'];
public function user() {
return $this->belongsTo('App\User', 'updated_by');
}
public function category() {
return $this->belongsTo('App\Category');
}
}
Like I said is everything working as expected, when I use Postman, to send the POST-Request. But with my fetch()-function I get a 200-response, but in the database there is only "created_at" and "updated_at" filled and the rest is just an empty string. The Log-statment in the EventController shows, that is seems as the Request-object is empty. But looking in the Firefox-developer tools I see that the data is send in the request body.
So any ideas? I can also send other code-files if needed.
Thank you all already for your help Marco
EDIT: As it was not obvious, the API and Frontend are both running on the same host; localhost:8000 so it's not a CORS-issue. I had first running the Frontend on localhost:8080 but I eliminated that by running both on the same server.
As expected when noone was really able to answer my question directly, my fault was not obvious. I recognized today with a freind, that the request I actually send is different from what I wrote in the code. With some more searching I found out that my webpack.config was somehow misconfigured and published the code in the wrong directory. But since there was already an "older" js-file the page looked correct but didn't have the changes of my API-Call.
TL;DR Pay attention that everything lies where you need it and then the code above is correct :-)
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