I want to send POST data from NodeJS server (localhost:4000) to PHP symfony server (localhost:8000)
But every time when I'm trying to send it, I got always same result => empty array.
Here is my code:
NodeJS
var data = {
method: "disconnectFromGame",
};
var querystring = require("querystring");
var qs = querystring.stringify(data);
var qslength = qs.length;
var options = {
hostname: "http://localhost:8000",
port: 80,
path: "/game/api",
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': qslength
}
};
var buffer = "";
var req = http.request(options, function (res) {
res.on('data', function (chunk) {
buffer += chunk;
});
res.on('end', function () {
console.log(buffer);
});
});
req.write(qs);
req.end();
It works fine, debugger stop me at the specific breakpoint, so communication is OK, but $request has always empty parameters..
PHP Symfony 5
public function engineApi(Request $request) {
$user = $this->getUser();
if(!$user) {
return $this->redirectToRoute("app_login");
}
if (!$request->isXMLHttpRequest()) {
return $this->redirectToRoute("app_homepage_show");
}
$entityManager = $this->getDoctrine()->getManager();
$data = $request->request->all();
$api = new Api($data, $user, $entityManager);
return $api->processMethod();
}
Your script works :
How do you get the picture of your dump ? Because I think, this is where you made a mistake.
When you execute the NodeJs script, did you get a response from the Symfony server in your console ? Because if you put a dump() in your Symfony, you should have something like this (which is the raw view of html response with dump data from Symfony) :
Related
I have two pieces of code, the Front-end in React and the Bakc-end in Laravel, the problem is im calling the API to get an array of a SQL join but in the useEffect React Hook it doest get the info, but if i make a button to get it works, i don't know why the useEffect Hook isn't working properly
I partially solved the question by treating the response as an array but if you are sending more than 1 thing i still dont know what to do
I have this pieces of code
Laravel:
public function show($id)
{
$returned = response('El lote solicitado no existe', Response::HTTP_BAD_REQUEST);
$lote = DB::table('lotes')
->leftjoin('articulos', 'lotes.idArticulo', '=', 'articulos.id')
->select('lotes.idLote', 'lotes.idArticulo', 'lotes.cantidad', 'lotes.consumoPreferente', 'lotes.observaciones', 'articulos.descripcion')
->where('lotes.id', $id)
->get();
if($lote){
$returned = response($lote, Response::HTTP_OK);
}
return $returned;
}
React:
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data)
} catch (e) {
console.log(`Error ${e}`)
}
}
The problem is that lote isn't setting in the useEffect hook, but if i call the getLote function outside of it works.
Another issue is that if i change the laravel part to this works properly on the useEffect call:
I think the key is here, if i use the 'findOrFail' it works properly but if make a SQL query it doesn't, but if im using the async - await it should wait, rigth?
$lote = Lote::findOrFail($id);
if($lote ){
$returned = response($lote , Response::HTTP_OK);
}
return $returned;
Also to mention im ussing axios to make the calls, could it be the problem too?
Do you know what could be happening?
The first thing you need to do is to make sure that id is already defined in useEffect, so you need to re-write useEffect like this:
useEffect(() => {
if(!id) {
return;
}
document.title = `Lote ${id}`
getLote()
}, [id]);
also, I would recommend putting function in useCallback
const getLote = useCallback(async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data)
} catch (e) {
console.log(`Error ${e}`)
}
}, [id]);
It is crucial to add relevant dependencies in deps array.
I solved the question by doing an intermediate step
If the data that is being sended is only one object in the array
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data[0])
} catch (e) {
console.log(`Error ${e}`)
}
}
If the data that is being sended are more than one object in the array
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
let newLote = response.data
setLote(newLote)
} catch (e) {
console.log(`Error ${e}`)
}
}
I don't know why this happens but this solution worked for me
I'm using Angular with PHP and trying to post an object. Request status is 200, but $_POST array is empty. Data I'm sending is a valid JSON Object.
sendTweet(){
if(!this.username || !this.tweet){
alert("Enter username or tweet");
return;
}
const newTweet:Tweet = {
username: this.username,
tweet: this.tweet
}
//Call Service
this.testService.postTweet(newTweet).subscribe((response)=>{console.log(response)},
(err:any)=>{
console.log(err.message);
});
}
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
postTweet(tweet:Tweet):Observable<Tweet>{
const url = `${this.apiUrl}/?page=submit&action=add`;
return this.http.post<Tweet>(url,tweet, httpOptions);
}
PHP:
if (isset($_POST['tweet'])&&isset($_POST['username'])) {
//Sending tweet to the db
} else{
print_r($_POST);
}
i dont know if its a backend problem with php but in my project i have it a little bit diferent (i am using .net core for backend)
for example in my project:
//service component WebScrapLinkService
get(): Observable<Any[]> {
return this.http.get<Any[]>(this.url)
.pipe(map(res => res));
}
//main component
getRegisters() {
this.getProductsSub = this.crudService.get()
.subscribe(data => {
this.registers = data;
})
}
//variables
public registers: Array<object> = [];
//the service goes in the constructor
private crudService: WebScrapLinkService
this works fine for me, i hope it is useful for you
It was just me not knowing that in PHP you have to parse HTTP_RAW_POST_DATA in order to get the data.
I am posting data to Laravel and expect a success response, but it catches the exception TypeError: Network request failed. Using get methods and login post methods using Laravel passport works all fine.
Adding 'Content-Type': 'application/json' to headers creates Network request failed for the login methods.
Postman returns valid errors or success, so works totally as expected.
Debugging showed that the request has been sent to Laravel and routing is correct as Visual Studio Code debugger stops at a breakpoint at return response.
public function postMessages()
{
...
return response()->json(['success' => 'success'], 200);
}
Route::middleware('auth:api')->group(function () {
Route::post('messages', 'Api\ChatController#postMessages');
});
export const fetchApi = async (endPoint, method = 'get', body = {}) => {
const accessToken = authSelectors.get().tokens.access.value;
const accessType = authSelectors.get().tokens.access.type;
let headers = {
...(accessToken &&
{
Authorization: `${accessType} ${accessToken}`
}
)
};
let response;
if (method=='get' || Object.keys(body)==0 ) {
response = await fetch(`${apiConfig.url}${endPoint}`, {
method: method,
headers: headers
});
} else {
var formData = new FormData();
Object.keys(body).forEach(type => {
formData.append(type, body[type]);
});
response = await fetch(`${apiConfig.url}${endPoint}`, {
method: method,
headers: headers,
body: formData
});
console.log('fetch response: ' + JSON.stringify(response));
}
let responseJsonData = await response.json();
return responseJsonData;
}
export const postMessages = (eidug, type, name, messages) => fetchApi('/message', 'post', {
'eidug': eidug,
'type': type,
'name': name,
'messages': messages
});
I expect a response without any exception like Postman. What can be going wrong?
Have you enabled CORS in the backend? Once open inspect->network and then run fetch. Show if there are any errors.
I have an API that requires a string parameter. I want to take the query parameter to the controller and process there. I tried $ajax_data = Input::get('query'); but it didnt work. Searched the same question but cant find a decent answer. Current error is $ajax_data is empty.
My ajax request:
const sendAPIRequest = function (csrf, f) {
$.ajax({
async: false,
url: 'api/apitest',
method: 'get',
data:{
query:"select?facet=on&q=*:*&rows=1&json.facet={Categories:{type:terms,field:price,limit:3}}"
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + tkid);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('X-CSRF-TOKEN', csrf.trim());
},
success: function (data) {
f(data);
},
error: function(xhr) {
//Do Something to handle error
}
});
};
My Controller API part:
public function apitest(){
$ajax_data = Input::get('query');
$user_type = UserAuthorizationHelper::user_authorization();
if ($user_type == Authorities::EDIT_ORGANISATIONS) {}
$query = new GuzzleHttp\Client();
try {
$response = $query->request('GET',SolrController::$url.$ajax_data);
} catch (GuzzleHttp\Exception\GuzzleException $e) {}
$data = $response->getBody()->getContents();
return response()->json(json_decode($data));
}
You are having a problem in this line:
$ajax_data = Input::get('query');
When you are making a request, Request object is sent with the data.
So, instead of Input replace it with Request's object, and you will get the desired output.
Something like this:
// Don't forget to import the Request's namespace
public function apitest(Request $request)
{
$ajax_data = $request->get('query');
// ... Rest of your code
}
I have a backbone script that calls a Slim REST service. GET requests are working fine, PUT requests are returning 404 Not Found. Note: this was working until my code was recently moved to a different server (and it works locally), so I'm guessing it has something to do with an Apache config setting. Here's a snippet of the backbone script:
jQuery(document).ready(function ($) {
//define box model
var Box = Backbone.Model.extend({
url: function () {
var urlId = (this.id) ? this.id : "";
var myUrl = "/wp-includes/api/service.php/box/" + urlId;
return myUrl;
}
});
var BoxView = Backbone.View.extend({
tagName: "div",
template: $("#boxTemplate").html(),
initialize: function () {
this.model = new Box(box);
this.render();
},
saveBox: function(e){
e.preventDefault();
$("#boxMessage").empty();
var formData = {},
prev = this.model.previousAttributes();
$(e.target).closest("form").find(":input").not("button").each(function (){
var el = $(this);
formData[el.attr("id")] = el.val();
});
this.model.set(formData);
this.model.save(
{ },
{
success: function() {
$("#boxMessage").html("Box information saved.");
},
error: function() {
}
}
);
}
Here's a snippet of the Slim REST service:
<?php
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/workouts/:id', 'getWorkout');
$app->put('/box/:id', 'updateEventBox');
$app->run();
function getWorkout($id) {
echo json_encode(GetEventCompetitorWorkout($id));
}
function updateEventBox($id) {
$request = Slim::getInstance()->request();
$body = $request->getBody();
$eventBox = new EventBox(null);
$eventBox->TakeJson($body);
$eventBox->Save();
}
And here's the header info for the request:
Request URL:http://www.mydomain.com/wp-includes/api/service.php/box/1
Request Method:PUT
Status Code:404 Not Found
UPDATE: just tested a POST to the same service and it worked fine. PUT still fails.
I've found it not too uncommon that some servers only have GET,POST,HEAD enabled and that PUT,DELETE which are needed for REST are not enabled. That could be the case.
To test for this you can tell Backbone to use "emulatated HTTP" by calling this before your code:
Backbone.emulateHTTP = true;
This will make backbone use only GET/POST requests however it will append to the querystring "_method=PUT" or "_method=DELETE" which you can use on the serverside to detect the intended HTTP verb.
So on the server side you need to do something like this like as the first line of your index.php file (before any of the framework loads):
if (isset($_REQUEST['_method'])) $_SERVER['REQUEST_METHOD'] = $_REQUEST['_method'];