I have an Inbox with internal messages from my clients. When I click on the list over the name I'm requesting using jQuery $.ajax so:
$.ajax({
url: 'messages/retrieve/' + client_id,
}).done( function(data) {
$('.messages-dialog').html(data);
});
My controller should return a variable with json data? I understand it should dump it on a view and I should treat it there but how to do it if is client side?
I don't know if is better to treat and create the html structure into controller and than just load it in .messages-dialog with jQuery.html();
Sorry I'm a little lost on that issue.
You can use jQuery.ajax() method, as in the example above. Also see the official documentation with examples http://api.jquery.com/jquery.ajax/.
Besides you can use jQuery.get() and jQuery.post() methods depending on how and what you will send. You can use this methods as shown below:
var url = 'messages/retrieve/' + client_id;
$.post( // for example
url,
function( data ) {
$('.messages-dialog').html(data);
});
See official documentation with examples here: http://api.jquery.com/get/, http://api.jquery.com/jQuery.post/.
Server handler should be like as below:
use JsonResponse; // you must specify the exact component (I use this)
/**
* Change message in dialog // for example
*/
public function changeDialogMessageAction(Request $request) {
// request data processing
$response = new JsonResponse();
$response->setData(array(
// new data for returning to client
));
return $response; // your data, which will be handled in callback
}
You shouldn't create HTML structure in the controller. It's bad style! JavaScript has asynchronous event model, and you should use it. Controller must handle / transform data, which were passed by you and then return back. jQuery callback must embed received handled / transformed data in DOM.
Related
I'm using JQuery DataTables with Vue 2. The below snippet shows how I'm using it with a JSON data source fetched from a custom method using the wretch package (it also handles authorization).
...
mounted: function () {
this.dataTable = window.$(this.$el).DataTable({
data: this.getGridData,
columns: this.getColumns,
// serverSide: true
});
},
...
This method is working fine. Now I want to enable the serverSide feature to control pagination and search without using the ajax option.
My backend application is running in .NET Framework. I have created my response data structure as shown here, but it doesn't seem to help.
Simply, I want to use my custom method to fetch data into the DataTable while using the serverSide feature.
Is this possible? I'm looking forward to your help.
DataTables has various different forms for its ajax option.
One of these is as follows:
$('#example').dataTable( {
"serverSide": true,
"ajax": function (data, callback, settings) {
// whatever logic you want to use can go here,
// as long as it evaluates to a valid JSON structure
// expected by DataTables, as a server-side response.
callback(
resultsOfYourLogic
);
}
} );
You can read its description in the linked documentation - but it basically states:
As a function, making the Ajax call is left up to yourself allowing complete control of the Ajax request. Indeed, if desired, a method other than Ajax could be used to obtain the required data...
Therefore, you can use this - with serverSide: true - to use any alternative method you wish to source your data.
Example:
"ajax": function (data, callback, settings) {
var dataSet = yourCustomFunction(data);
callback(
dataSet
);
},
Here, the custom function is invoked first, returning the JSON which needs to be displayed. The request data is passed to that custom function. Then the results of that custom function are placed in the callback.
One important note here is: The data parameter in the callback will be pre-populated with the server-side request data (automatically created by DataTables whenever the user sorts/filters/pages). So you will need to handle this request data, to know how your response data needs to be built.
(The response data structure you link to in your question, is the correct structure.)
I'm making a site with several calls to PHP via AJAX, right now AJAX uses POST to get a echoed string from PHP and then compares that in a switch and then does what is required. Example in the code below
function submitPHP(dataForPHP){
//Runs ajax request
$.ajax({
type : "POST",
url : 'initPHP.php',
dataType : 'text',
data : dataForPHP,
success : function(data){
//Checks echoed data from PHP
switch(data){
case "LOGIN_ACCEPTED":
loggedInFunction();
break;
case "LOGIN_FAILED":
loggedInFailedFunction();
break;
}
}
});
}
I'm thinking if there is a way for the PHP to return what function (like "loggedInFunction();") I want to call instead of a string that I then have to compare and then call the function? I can change the AJAX to use JSON instead if that does it.
I've been looking around on other similar questions here on stack on most of them want to echo a whole function which is not what I want to do.
Thanks in advance!
I'd do this.
use HTTPS to perform login, HTTP really is insecure nowadays;
create a controller object with all allowed methods (actions);
call an action of that controller.
The idea of having a controller is convenient on several levels:
security: if a method is not in the controller you cannot call it, so it is a way to know what can be called and what is absolutely not possible to call;
cohesion: the methods are all next to each other and easier to maintain;
encapsulation: if there is any state it can be held easily inside the context of that object.
This is an example:
loginController = {
"acceptAction": function () {
},
"failAction": function () {
}
};
You can now call those methods from the AJAX handler. Say the server tells you what you must do. A verb so to speak, such as accept or fail. You can then do:
"success": function (data) {
loginController[data + "Action"]();
}
And that's it.
BTW: this is just the very basic MVC pattern. Oldie but goldie :)
The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}
I'm trying to download, parse and show a list, from the XML received from my server using Backbone.js. The code is like:
var Item = Backbone.collection.extend({
url: "http://myurl.com/file.xml",
parse: function() {
console.log("parse");
},
success: function(data) {
console.log(data);
},
error: function() {
console.log("error");
}
});
var View1=Backbone.view.extend({
initialize: function() {
var item = new Item();
item.fetch();
}
});
When I check it in the Chrome extension, the XML file is getting downloaded but the breakpoints placed in the parse, success, error directly lands to the error.
And it has 3 arguments, but I'm unable to extract any information from that.
Backbone does not support fetching XML, hence, you'll need to override the sync method to provide your own custom parsing functionality. If you don't want to have to mess with Backbone internals, try doing your $.ajax GET first, parse your response into a proper JSON Array and then use that array with a Backbone#Collection-reset.
Backbone#Collection-fetch
The server handler for fetch requests should return a JSON array of
models.
Backbone#Sync
With the default implementation, when Backbone.sync sends up a request
to save a model, its attributes will be passed, serialized as JSON,
and sent in the HTTP body with content-type application/json. When
returning a JSON response, send down the attributes of the model that
have been changed by the server, and need to be updated on the client.
When responding to a "read" request from a collection
(Collection#fetch), send down an array of model attribute objects.
I prefer to use jQuery with my ASP.NET MVC apps than the Microsoft Ajax library. I have been adding a parameter called "mode" to my actions, which I set in my ajax calls. If it is provided, I return a JsonViewResult. If it isn't supplied, I assume it was a standard Http post and I return a ViewResult.
I'd like to be able to use something similar to the IsMvcAjaxRequest in my controllers when using jQuery so I could eliminate the extra parameter in my Actions.
Is there anything out there that would provide this capability within my controllers or some simple way to accomplish it? I don't want to go crazy writing code since adding a single parameter works, it just isn't ideal.
Here's an except from MVC RC1 release notes - Jan 2009
IsMvcAjaxRequest Renamed to IsAjaxRequest
The IsMvcAjaxRequest method been
renamed to IsAjaxRequest. As part of
this change, the IsAjaxRequest method
was updated to recognize the
X-Requested-With HTTP header. This is
a well known header sent by the major
JavaScript libraries such as
Prototype.js, jQuery, and Dojo.
The ASP.NET AJAX helpers were updated to send this header in
requests. However, they continue to
also send it in the body of the form
post in order to work around the issue
of firewalls that strip unknown
headers.
In other words - it was specifically renamed to be more 'compatible' with other libraries.
In addition, for anyone who hasnt read the full release notes but has been using previous versions - even as recent as the beta - I STRONGLY recommend you read them in full. It will save you time in future and most likely excite you with some of the new features. Its quite surprising how much new stuff is in there.
Important note: You will need to make sure you upgrade the .js file for MicrosoftAjax.MVC (not the exact name) if upgrading to RC1 from the Beta - otherwise this method won't work. It isn't listed in the release notes as a required task for upgrading so don't forget to.
See Simons answer below. The method I describe here is no longer needed in the latest version of ASP.NET MVC.
The way the IsMvcAjaxRequest extension method currently works is that it checks Request["__MVCASYNCPOST"] == "true", and it only works when the method is a HTTP POST request.
If you are making HTTP POST requests throug jQuery you could dynamically insert the __MVCASYNCPOST value into your request and then you could take advantage of the IsMvcAjaxRequest extension method.
Here is a link to the source of the IsMvcAjaxRequest extension method for your convenience.
Alternatively, you could create a clone of the IsMvcAjaxRequest extension method called
IsjQueryAjaxRequest that checks Request["__JQUERYASYNCPOST"] == "true" and you could dynamically insert that value into the HTTP POST.
Update
I decided to go ahead and give this a shot here is what I came up with.
Extension Method
public static class HttpRequestBaseExtensions
{
public static bool IsjQueryAjaxRequest(this HttpRequestBase request)
{
if (request == null)
throw new ArgumentNullException("request");
return request["__JQUERYASYNCPOST"] == "true";
}
}
Checking from an action if a method is a jQuery $.ajax() request:
if (Request.IsjQueryAjaxRequest())
//some code here
JavaScript
$('form input[type=submit]').click(function(evt) {
//intercept submit button and use AJAX instead
evt.preventDefault();
$.ajax(
{
type: "POST",
url: "<%= Url.Action("Create") %>",
dataType: "json",
data: { "__JQUERYASYNCPOST": "true" },
success: function(data) {alert(':)');},
error: function(res, textStatus, errorThrown) {alert(':(');}
}
);
});
Why don't you simply check the "X-Requested-With" HTTP header sent automatically by most Javascript libraries (like jQuery) ?
It has the value 'XMLHttpRequest' when a GET or POST request is sent.
In order to test it you should just need to check the "Request.Headers" NameValueCollection in your action, that is :
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
return Json(...);
else
return View();
This way, you can simply differentiate regular browser requests from Ajax requests.
Ok, I have taken this one step farther and modified my jQuery file to load the additional parameter into the post data, so I don't have to repeat the "__JQUERYASYNCPOST: true" for every call to post. For anybody that's interested, here's what my new definition for $.post looks like:
post: function(url, data, callback, type) {
var postIdentifier = {};
if (jQuery.isFunction(data)) {
callback = data;
data = {};
}
else {
postIdentifier = { __JQUERYASYNCPOST: true };
jQuery.extend(data, postIdentifier);
}
return jQuery.ajax({
type: "POST",
url: url,
data: data,
success: callback,
dataType: type
});
}
I added the "postIdentifier" variable as well as the call to jQuery.extend. Now the Helper explained in spoon16's response works without having to add any thing special to my page-level jQuery code.