Regarding your ajax call to the json generating contoller, method
is the more modern term rather than type
since JQuery 1.9
jQuery.ajax({
method: 'POST', // method is more modern than type
url: 'index.php?option=com_daily&task=ajax.initialisePerson&format=json',
data: registration,
success: (function (response) { ...
I haven't personally build an ajax-powered component yet, but there is a dedicated tutorial for this that shows a more readable syntax for passing the parameters of the ajax call.
https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Adding_AJAX
As for you controller, be very careful to only pass valid json on every possible response.
You are correct in identifying that wrapping your json string in (
and );
will break the string syntax, but you need to check your other response strings as well. With echo $callback . "(".json_encode($result).");";
, $callback
will break your json string too.
My recommendation is to perform all of your conditional handling and save all of your data into a $response
variable. (I always push data into my $response
array as associated elements like:
if ($condition === true) {
$response['message'] = "pass"; // whatever
$response['data'] = [1,2,3]; // whatever
} else {
$response['message'] = "fail"; // whatever
$response['error'] = "Syntax Error in X Query"; // whatever
}
Then I pass it back via a tidy little script-ending Joomla feature:
echo new JResponseJson($response);
This way, your php data is always perfectly encoded and the encoding call is only performed once at the end.
Now, when the data is passed back to jQuery as a response string, use response = JSON.parse(response);
to convert the string into something that javascript can chew on. If my response data can include optional elements, I check if it exists before I try to access it by writing an in
condition (to prevent generating warnings).
Here's a taste of that:
success(function (response) {
//console.log(JSON.stringify(response)); // see what Joomla generates for you
response = JSON.parse(response);
if ("message" in response.data) {
if (response.data.message == "pass") {
if ("data" in response.data) {
console.log(response.data.data);
} else {
console.log("uhoh, 'data' element not found in response.data");
}
} elseif (response.data.message == "fail") {
if ("error" in response.data) {
console.log(response.data.error);
} else {
console.log("uhoh, 'error' element not found in response.data");
}
} else {
console.log("Unknown response.data.message value");
}
} else {
console.log("uhoh, 'message' element not found in response.data");
}
}
Sometimes I use message
as a key for a value that I want to display in a bootstrap box. Sometimes I use alert
as a key for a value that I want to display as a javascript popup/alert. Never offer raw mysql error codes or messages in the response, if you are going to pass back an error
element, make it specific enough to guide you and your users, but general enough that malicious parties can't derive useful details from it. When you isolate separate values in this way, it can make manipulating the data in your javascript cleaner and more intuitive for other programmers.