Symfony3 send AJAX POST request - javascript

I want to send two variables id and commentary through an AJAX POST request.
The problem is that I don't get the POST variable but the route is reached.
JS:
$.post(Routing.generate('ajax_savecommentary', { id:id, commentary:commentary }),
function(response)
{
}, "json");
Symfony:
public function saveCommentaryAction()
{
if (!$this->get('session')->get('compte'))
return $this->redirect($this->generateUrl('accueil'));
$request = $this->container->get('request_stack')->getCurrentRequest();
$isAjax = $request->isXMLHttpRequest();
if ($isAjax)
{
$information = $this->getDoctrine()->getManager()->getRepository('CommonBundle:Information')->find($_POST['id']);
$information->setCommentaire(str_replace('\n', '\\n', $_POST['commentary']));
$this->getDoctrine()->getManager()->flush();
$response = array("code" => 100, "success" => true, 'commentary' => $_POST['commentary']);
return new Response(json_encode($response));
}
$response = array("code" => 0, "success" => false);
return new Response(json_encode($response));
}
The error:
http://localhost/MyProject/web/app_dev.php/ajax/save/commentary/?id=61&commentary=MyCommentary.
{"code":0,"success":false}
More Symfony error:
GET Parameters
Key/Value
commentary/MyCommentary
id/61
And the routing is case needed:
ajax_savecommentary:
defaults: { _controller: CommonBundle:Default:saveCommentary }
path: /ajax/save/commentary/
options:
expose: true

Try using the request passed to the Controller Action instead of retrieve it from the container. So try this:
use Symfony\Component\HttpFoundation\Request;
...
public function saveCommentaryAction(Request $request)
{
if (!$this->get('session')->get('compte'))
return $this->redirect($this->generateUrl('accueil'));
$isAjax = $request->isXMLHttpRequest();
instead of this:
public function saveCommentaryAction()
{
if (!$this->get('session')->get('compte'))
return $this->redirect($this->generateUrl('accueil'));
$request = $this->container->get('request_stack')->getCurrentRequest();
$isAjax = $request->isXMLHttpRequest();
UPDATE:
You can restrict your routing with Customized Route Matching with Conditions, as example on your case as follow:
ajax_savecommentary:
defaults: { _controller: CommonBundle:Default:saveCommentary }
path: /ajax/save/commentary/
options:
expose: true
condition: "request.isXmlHttpRequest()"
methods: [POST]
UPDATE:
There is a typo in the routing generation in the JS side:
$.post(Routing.generate('ajax_savecommentary', { id:id, commentary:commentary }),
function(response)
{
}, "json");
you pass the data as argument of the routing.generate function so it concatenate the params as query string. so try this:
$.post(Routing.generate('ajax_savecommentary'), { id:id, commentary:commentary },
function(response)
{
}, "json");
Another advice is about to use the $request object for obtain the data instead of the superglobal PHP attribute, so use:
$request->request-get('commentary');
instead of:
$_POST['commentary']
More info here in the doc.
Hope this help

Related

Call Restlet from User Event Script Error INVALID_LOGIN_ATTEMPT

I am trying to access Restlet from User Event script but i am receiving error: body":"error code: INVALID_LOGIN_ATTEMPT\nerror message: Invalid login attempt. Do i need to pass credentials too? what should i pass client id, client secret? is there another way?
I also tried url.resolveScript but no luck.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope Public
*/
define(["N/https", "N/log", "N/record", "N/url" ],
function(https, log, record, url) {
function beforeLoad(context) {
// log.debug('beforeLoad Triggered');
// context.newRecord;
// context.type;
// context.form;
return;
}
function afterSubmit(context) {
log.debug('Before code');
var record = context.newRecord;
var requestBody = {
"recordId": record.id,
"recordType": record.type,
};
var output = url.resolveScript({
scriptId: '1157',
deploymentId: '1',
});
var output1 = 'https://12345-sb5.restlets.api.netsuite.com';
log.debug('After code', output );
var response = https.post({
url: output1 + output,
body: requestBody,
});
if (response.code === 200) {
// success!
} else {
// handle error
}
log.debug('After code', response );
return;
}
function beforeSubmit(context) {
// log.debug('beforeSubmit Triggered');
// context.newRecord;
// context.oldRecord;
// context.type;
return;
}
return {
beforeLoad : beforeLoad,
afterSubmit : afterSubmit,
beforeSubmit : beforeSubmit
}
})
Why do you need your UE Script to submit and trigger your RESTlet every record submit?
Below could work for ClientScript, just not sure if saveRecord (only when the Submit/Save is clicked) entry point will trigger this.
var requestBody = JSON.stringify({
recordId: record.id,
recordType: record.type
});
var output = url.resolveScript({
scriptId: '1157',
deploymentId: '1'
});
var response = https.post({
url: output,
body: requestBody
});
Previously you could manipulate the cookies and pass it. However, it's no longer the case and Server Scripts cannot call Server Scripts unless you pass Authentication which is a pain if you have no library. Oauth1 + SHA256 is complicated to figure out without libraries.
You could probably approach this on another angle depending on your use case. At this moment, it isn't clear why you want AfterSubmit to call RESTlet. If you do this, if you have routine Scheduled Scripts that touches that record and saves the record, it will keep triggering your AfterSubmit unless you place an if statement.
try https.requestRestlet
var response = https.requestRestlet({
body: JSON.stringify({
"recordId": record.id,
"recordType": record.type,
}),
deploymentId: '1',
method: 'POST',
scriptId: 1157,
});

Vue js parameter can't get in route

I use VueJS and laravel but now I can't get parameter value, please help me to solve this problem.
my VueJS code:
getTestData:function () {
let config = {
params: {
id: 1
}
};
axios.post('{{ route('get_user_data') }}', config)
.then(function (response) {
console.log(response);
// app.posts=response.data;
})
.catch(error => {
})
},
My Controller code:
public function testData(Request $request)
{
// how to get this value?
}
My route
Route::post('get-user-data','TestController#testData')->name('get_user_data');
You don't actually need a post request to get some values out of database. A get request would be more suitable.
You need to have the param in the route definition
Route::get('get-user-data/{id}','TestController#testData')->name('get_user_data');
//If you want to use post route
Route::post('get-user-data/{id}','TestController#testData')->name('get_user_data');
Then in controller method you can get the value out of the request
public function testData(Request $request)
{
$id = $request->route('id');
}
params are the URL parameters to be sent with the request
You could retrieve input from query string in your controller as:
public function testData(Request $request)
{
$id = $request->query('id');
}

retrieve user from database from javascript

I am making an application in Laravel and I need to retrieve a user from the database from javascript, from its id.
Something like:
User :: find (id);
or:
DB :: table ('users') -> find (id);
but in javascript
I would consider using AJAX.
your other JS code
...
$.ajax({
type: "POST",
url: "to your controller",
data: {
'user_id' : user_id,
},
success: function (data) {
userdata1 = data.data1;
userdata2 = data.data2;
...something
}
});
And the controller would look something like this
class SomeController extends Controller
{
public function somefunction(Request $request)
{
$user = User::find($request->user_id);
... do other stuff
return response()->json([
'data1' => someValue1;
'data2' => someValue2;
]);
}
}
If you only need User's data, you can simply use route model binding and
class SomeController extends Controller
{
public function somefunction(User $user)
{
return response()->json([
'data1' => $user->name;
'data2' => $user->addr;
]);
}
}
There might be a better solution, but it works.
Don't know how exactly your code is, but if User's data has been already sent to view from controller, you can just do
var x = "<?php echo $user->somedata ?>"
in you JS code

Send a list of parameters in angular and change route

I trying to call other route in angular, similar this
$location.path($scope.productPath+"/approveProducts/").search({ids});
I want send the list of ids to other controller but the ids are sending by url
http://localhost:8080/#/product?ids=1130&ids=1132&ids=7428&ids=15574&ids=15579&ids=15580&ids=6798968768697789
I need send ids similar a post requisition, not in a url, because i have a many ids in my call
How i do this in angular, send parameters and change my route to other controller?
I believe a better approach might be to utilize the angularjs service/factory to persist your data.
example:
.service('AngularJsService', function() {
var listOfIds = [];
return {
saveData: function(theIdsToSave) {
listOfIds = theIdsToSave;
},
getData: function () {
return listOfIds;
}
}
}
.controller('OriginatingController', function($location, AngularJsService) {
function navigateToTargetController() {
AngularJsService.saveData([1,2,3,4]);
$location.path('pathToTargetController');
}
}
.controller('TargetController', function($location, AngularJsService) {
function retrieveData() {
var ids = AngularJsService.getData();
// ids = [1,2,3,4]
}
}
You can use $http for send your params and then change your route
var req = {
method: 'POST',
url: 'http://example.com',// address for sending ids
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){
// this you can to change your url
$location.path($scope.productPath+"/approveProducts/");
}, function(){...});

FOSUserBundle AJAX Login with Symfony2 (routing)

I'm trying to make the AJAX authentication work with FOSUserBundle.
I have created an Handler directory with a AuthenticationHandler class :
<?php
namespace BirdOffice\UserBundle\Handler;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface
{
private $router;
private $session;
/**
* Constructor
*
* #param RouterInterface $router
* #param Session $session
*/
public function __construct( RouterInterface $router, Session $session )
{
$this->router = $router;
$this->session = $session;
}
/**
* onAuthenticationSuccess
*
* #param Request $request
* #param TokenInterface $token
* #return Response
*/
public function onAuthenticationSuccess( Request $request, TokenInterface $token )
{
// if AJAX login
if ( $request->isXmlHttpRequest() ) {
$array = array( 'success' => true ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
return $response;
// if form login
} else {
if ( $this->session->get('_security.main.target_path' ) ) {
$url = $this->session->get( '_security.main.target_path' );
} else {
$url = $this->router->generate( 'home_page' );
} // end if
return new RedirectResponse( $url );
}
}
/**
* onAuthenticationFailure
*
* #param Request $request
* #param AuthenticationException $exception
* #return Response
*/
public function onAuthenticationFailure( Request $request, AuthenticationException $exception )
{
// if AJAX login
if ( $request->isXmlHttpRequest() ) {
$array = array( 'success' => false, 'message' => $exception->getMessage() ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
return $response;
// if form login
} else {
// set authentication exception to session
$request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
return new RedirectResponse( $this->router->generate( 'login_route' ) );
}
}
}
I have created a login Javascript function :
function login() {
$.ajax({
type: "POST",
url: Routing.generate('check_login_ajax'),
dataType: 'json',
data: {
_username: $('#username').val(),
_password: $('#password').val(),
_remember_me: false,
_csrf_token: $('#_csrf_token').val()
}
}).done(function(data) {
console.log(data);
}).fail(function(data) {
console.log(data);
});
}
In my routingAjax.yml, I have added the following lines to override the FOSUserBundle security route :
check_login_ajax:
pattern: /check_login_ajax
defaults: { _controller: FOSUserBundle:Security:check }
requirements:
_method: POST
options:
expose: true
In my global security.yml file, I have added the check_path, success_handler and failure_handler parts :
firewalls:
main:
pattern: ^/
form_login:
login_path: fos_user_registration_register
check_path: check_login_ajax
success_handler: user.security.authentication_handler
failure_handler: user.security.authentication_handler
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout:
path: fos_user_security_logout
target: /
anonymous: true
My first issue is : the AJAX return this message: "Invalid CSRF token." (but I send a good one generated in PHP, maybe I missed something doing it). Here is my PHP code for it :
<?php
$csrfProvider = $this->container->get('form.csrf_provider');
$csrfToken = $csrfProvider->generateCsrfToken('popUpUser');
?>
Second issue : my login page (not the AJAX one) is not working anymore because the orignal route of FOSUserBundle login has been overwritten.
PS : I have posted a message yesterday : FOSUserBundle (login / register) + AJAX + Symfony2 but I have badly explained my problem. Sorry by advance.
First Issue: You are sending an invalid CSRF token. In Symfony 2.3 you could generate it using {{ csrf_token('authenticate') }} inside the template's input's value.
Second issue: Do not overwrite the route, simply use the original route: fos_user_security_check.
In general: if you use an AuthenticationSuccessHandler extending Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler your method could look something like this:
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
if ($request->isXmlHttpRequest()) {
return new JsonResponse(array('success' => true));
}
return parent::onAuthenticationSuccess($request, $token);
}
Do something similar for an AuthenticationFailureHandler extending Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler.

Categories

Resources