How to return ajax response with error http code from PrestaShop ModuleFrontController? - prestashop

I start working with PrestaShop 1.7.6 (before I worked with Symfony) and I write few custom modules to PrestaShop, but now I want send json data from my front controller module to user. Everything works fine if I send json with http code 200, but now I want send error message with proper http code (e.g 400). In Symfony I can do that by using JsonResponse (I try to do that here but it's not working as expected).I saw in presta controller are just two methods with ajax response (ajaxDie - which is deprecated and ajaxRender), but both of them doesn't takes as parameter http code response and always send 200.
if (!$product) {
$json = Tools::jsonEncode(['status' => false]);
$this->ajaxRender($json);
//return new JsonResponse($json, Response::HTTP_BAD_REQUEST);// doesn't send proper code
}
Can anyone tell me how to send error code from module front controller which extends ModuleFrontController?? Now only possible to me action is send error message with http code 200 (but I think it's bad idea to send error with that code). Thanks a lot for any help.

The proper way to send and receive data using AJAX is displayed below.
More information can be found at Prestashop Docs
Ajax post
$.ajax({
type: 'POST',
dataType : 'json',
url: 'linktoyourfile.php',
data: { action: 'getMyrequest' },
success: function(data) {
alert(data.result);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error: ' + textStatus + ' ' + errorThrown);
}
});
Module Front Controler
class TestModuleFrontController extends ModuleFrontController
{
public function init()
{
parent::init();
}
public function displayAjaxGetMyrequest()
{
// ERROR HANDELING
if ($this->errors) {
die(Tools::jsonEncode(array('hasError' => true, 'errors' => $this->errors)));
} else {
echo Tools::json_encode(array('result' => 'test result'));
}
}
}

Related

How to make an admin ajax call in prestashop 1.7.6

I'm trying to make an ajax call in Prestashop Admin:
I created a module without a config page. It just add a button in some backoffice page, I'm trying to make an ajax call to my module file without success.
Making an ajax call in frontend is working (I added an ajax.php file in my modules/mymodule/controller/front/ directory), I tried to do the same thing for admin but it's not working at all.
What I've done:
loading the js file from actionAdminControllerSetMedia is ok
adding this in the composer.json file:
"autoload": {
"psr-4": {
"MyModule\\Controller\\": "controllers/admin/"
},
"config": {
"prepend-autoloader": false
},
created the controllers/admin/ajax.php file with this code (based on this documentation code):
namespace MyModule\Controller;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
class DemoController extends FrameworkBundleAdminController
{
public $auth = false;
public $ssl = true;
public $ajax = true;
public $errors = false;
public $message;
public function __construct()
{
parent::__construct();
}
public function initContent()
{
parent::initContent();
}
public function postProcess()
{
PrestaShopLogger::addLog("MODULE CONTROLLER OK ", 1);
}
public function displayAjax()
{
$this->ajaxDie(json_encode(array('success'=> !$this->errors, 'message' => $this->message)));
}
}
Then I tried to call the ajax from different way in js but never worked (the post query return is a message from prestashop "page not found" with http 200 response.
the doc isn't very helpful and I only find old messages/ways to do (from Prestashop 1.7.5 I'd be able to create a custom Admin controller but it doesn't work), can someone explain me the steps to follow?
thanks
Assuming it is for a PS1.7+ module, using Symphony:
Declare a link in a method of your admin controller (src/Controller/Admin) e.g
$adminLink = $this->generateUrl()
and return in with:
return $this->render
In your views/js/back.js"
$.ajax({
url: adminLink,
type: 'POST',
async: false,
data: {
},
success: (data) => {
}
});
Note: check the generateUrl and render functions for the necessary arguments.

React Native Woocommerce API fails when parameters are set

I recently decided to give React Native a shot. I am running into some trouble communicative with Woocommerce using the react-native-woocommerce-api.
When I get all the products, it works great, but when I try to set an attribute to the HTTP call, it fails.
This works:
componentDidMount() {
console.log("Loading products...");
Woocommerce.get("products", {}).then(response => {
console.log(response);
});
}
This doesn't (per_page added):
componentDidMount() {
console.log("Loading products...");
Woocommerce.get("products", {per_page: 3}).then(response => {
console.log(response);
});
}
Error thrown:
Object {
"code": "woocommerce_rest_authentication_error",
"data": Object {
"status": 401,
},
"message": "Invalid signature - the signature doesn't match.",
}
HTTP request that works:
http://www.example.com/wp-json/wc/v3/products?oauth_consumer_key=###&oauth_nonce=###&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1560818379&oauth_version=1.0&oauth_signature=###=&
HTTP request that doesn't work:
http://www.example.com/wp-json/wc/v3/products?oauth_consumer_key=###&oauth_nonce=###&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1560817909&oauth_version=1.0&oauth_signature=###=&per_page=3
I should also add that when adding per_page=3 using Postman, it works. I don't know what difference it makes, the HTTP calls are very similar, it seems that only the uri parameters order are different.
Any help is appreciated! Been stuck on this the whole freaking day. :/
Open react-native-woocommerce-api.js in node_modules\react-native-woocommerce-api\lib\
then goto line 195 (_getOAuth().authorize function) and change:
params.qs = this._getOAuth().authorize({
url: url,
method: method
});
to
params.qs = this._getOAuth().authorize({
url: url + '?' + this.join(data, '&'),
method: method
});

Using NodeJS for our API, how to control what HTTP status codes are sent from Hapi?

We are using Hapi for our simple API. We have out own auth system, so if a user calls our API, but they are not authenticated, I want to send back a 401 HTTP status code.
I saw this post:
https://futurestud.io/tutorials/hapi-how-to-set-response-status-code
which offers this example:
handler: function (request, reply) {
var data = { key: 'value' }
reply(data).code(201)
}
So I started adding in response codes, including codes for our exceptions:
DB.knex.raw(query).then(function(result) {
var dataJson = [];
var responseJson = {};
for(var i in result[0]) {
dataJson.push({
"name": result[0][i]["name"],
"profile_id": result[0][i]["profile_id"],
"profile_type": result[0][i]["profile_type"],
"profile_classification": result[0][i]["profile_classification"],
"permalink": result[0][i]["permalink"],
"location": result[0][i]["location"],
});
}
responseJson["data"] = dataJson;
reply(responseJson).code(200);
})
.catch(function(e) {
console.error(e);
reply(e).code(500);
});
but I immediately got this error:
TypeError: query.then(...).catch(...).code is not a function
So... I guess I can't do this. I am confused by the error, since I am not calling ".code()" on the "catch", I am calling it on the reply().
We are using Boom, does that override the advice in the article? The article talks about Boom, but does not make clear that Boom overrides the earlier advice.

mean.js angular - express routing

I'm new to the MEAN stack and I'm having some trouble with routing...
I have a module called "applications".
the APIs i want on the server side are:
get: http://localhost:3000/api/applications/(_appid)
getByMakeathonId: http://localhost:3000/api/applications/makeathons/(_mkid)
Applications Service
function ApplicationsService($resource) {
return $resource('api/applications/:path/:applicationId', {
path: '#path',
applicationId: '#id'
}, {
get: {
method: 'GET',
params: {
path: '',
applicationId: '#_id'
}
},
getByMakeathonId: {
method: 'GET',
params: {
path: 'makeathon',
applicationId: '#_id'
}
},
update: {
method: 'PUT'
}
});
Server Routing
app.route('/api/applications').post(applications.create);
app.route('/api/applications').all(applicationsPolicy.isAllowed)
.get(applications.list);
app.route('/api/applications/makeathon/:makeathonId').all(applicationsPolicy.isA llowed)
.get(applications.applicationByMakeathonID);
1) what I'm getting when I call $save and the object and the save is successful, there is a call for .get, and the request URL is: http://localhost:3000/api/applications//56f15736073083e00e86e170 (404 not found)
the problem here of course is the extra '/' - How do I get rid of it.
2) when I call getByMakeathonId, the request url is: http://localhost:3000/api/applications/makeathon?id=56e979f1c6687c082ef52656 400 (Bad Request)
I do I configure so that I'll get the two requests that I want?
10x!
You are getting the repeated // in your request url because you have declared that there will be a :path in your applications resource, and you are providing an empty string to interpolate there.
As $resource is meant to provide RESTful interaction with your API, I think the most appropriate approach would be to have separate $resources to deal with applications and makeathons. Something like this:
For applications:
function ApplicationsService($resource) {
return $resource('api/applications/:applicationId', {
applicationId: '#id'
}, {
update: {
method: 'PUT'
}
});
}
For makeathons:
function MakeathonsService($resource) {
return $resource('api/applications/makeathons/:makeathonId', {
makeathonId: '#id'
}
});
}
/** your server route would then be updated to
* app.route('/api/applications/makeathons/:makeathonId')...
*/

Call Ajax Play FrameWork

I have a problem with ajax, play framework 2.1.1:
My Play Project
routes:
POST /sample/testapi controllers.Application.testapi()
GET /sample/ajax controllers.Application.ajax()
Application.java
public static Result testapi() {
DynamicForm dynamicForm = DynamicForm.form().bindFromRequest();
String data= dynamicForm.get("data");
Logger.debug(data);
return ok("<user no='1'><id>1</id><name>Peter</name></user>");
}
public static Result ajax() {
return ok(ajax.render());
}
When I call action "testapi" from ajax.scala.html through ajax
My ajax code
$.ajax({
url : "http:// localhost:3333/sample/testapi",
type: 'POST',
data: {data: "test"},
dataType: "text",
success : function(result) {
alert(result);
},
error : function(request,error) {
alert(error);
}
});
It working fine.
And I have a html file and I call to play project through ajax.
The action had been called, but not return result and show alert "error".
Please help me. Thanks.
I added "response().setHeader("Access-Control-Allow-Origin", "*");" to my action.
public static Result testapi() {
response().setHeader("Access-Control-Allow-Origin", "*");
DynamicForm dynamicForm = DynamicForm.form().bindFromRequest();
String data= dynamicForm.get("data");
Logger.debug(data);
return ok("<user no='1'><id>1</id><name>Peter</name></user>");
}
"response().setHeader("Access-Control-Allow-Origin", "*");" allow other domain call it.