I have a data entity that I use in two ways, I populate a table with some of its data when the page loads, and when you click a row of that column, I AJAX up the details of that item and display them in form fields. I'm using Spring-Roo generated REST endpoints on the server side, and Backbone.js on the client.
When the table loads, date fields have the format I expect, coming straight out of my MySQL database ("yyyy-MM-dd"). When I get my AJAX data, date fields come to me as Unix time values (e.g. "1323666000000").
I can convert that on the client side, but that's stupid. Any idea how I can get my json controller to not do this?
I've tried pushing those fields into my .java file and messing with the #DateTimeFormat annotation, but I can't see that makes any difference.
You can transform the date to any format you want for your JSON response.
In your case, you've been using the default JSON date transformer all the time for the java.util.Date type fields. This is basically what gets generated for you by the Spring Roo. Take a look and in your *_Roo_Json aspects and you will find smth. like this:
public java.lang.String PizzaOrder.toJson() {
return new JSONSerializer().exclude("*.class").serialize(this);
}
Such an implementation uses the flexjson.transformer.BasicDateTransformer class to transform the date for you. It is implemented like this:
public class BasicDateTransformer extends AbstractTransformer {
public void transform(Object object) {
getContext().write(String.valueOf(((Date) object).getTime()));
}
}
What you want is to use a different, more powerfull transformer. Luckily it comes with your Roo and it's called flexjson.transformer.DateTransformer. Now, in order to format your dates properly, just replace the default with the new transformer e.g. like this:
public java.lang.String PizzaOrder.toJson() {
return new JSONSerializer().exclude("*.class")
.transform(new DateTransformer("MM/dd/yyyy"), Date.class)
.serialize(this);
}
That's all :-)
Know that you may also apply different Date (and not only) transformations for different fields like this:
transform(new DateTransformer("MM/dd/yyyy"), "person.birthday")
For more info about the flexjson take a look at FLEXJSON project page.
Related
I have a Model Review that has a unix timestamp as 1 of it's attributes (table columns).
I use 2 accessors inside this model:
public function getReviewDateAttribute($value)
{
return strftime('%A %e %B %Y', $value);
}
public function getReviewDateIsoAttribute()
{
return Carbon::createFromTimestamp($this->review_date)->toDateTimeString();
}
getReviewDateAttribute works as expected and shows up in the collection of models when I write a query.
However getReviewDateIsoAttribute does not. What could be the reason for this?
A subquestion: If I use the same attribute in both functions, how can I use the original format as input value?
You should be adding it to the $appends array. It isn't spinning through all available methods looking for getXXXXXAttribute. The other one is used because it is an accessor for an actual attribute, this one is not an actual attribute.
class YourModel ....
{
protected $appends = ['review_date_iso'];
...
}
Laravel 5.5 Docs - Eloquent - Serialization - Appending Values to JSON
This is probably because ReviewDateIso is not an actual column and therefore will not show up in the model collections...you can access it directly by calling the method directly
$model->getReviewDateIsoAttribute()
According to the docs accessors a ways of changing the value of a column before it is returned to the method that queried it.
If you want it to show up when you call the collection as Json append it to the output with
protected $appends = ['name_of_attribute'];
I tried queries in tinker and with dd method. So I got confused since I cant view my new accessor in the attribute list.
I thought I missed something. Then later I noticed appended attributes are shown separately when we dd the query result than the usual attribute JSON.
I lost time thinking my accessor is not working. Its just I`m not checking in the right way or right place. So I``m attaching the following image, if anyone gets stuck on accessors like me, this might help them.
In fact it depends on what you are trying to achieve. If you are going to display anything in Blade for example, you can use whenever you want $object->review_date_iso to get this attribute value.
However if you are returning Json responses (for example API), you need to tell Eloquent model to append extra fields to your model when transforming to JSON format.
You probably have review_date attribute in your model (this is the column in database I suppose) but you don't have review_date_iso in your table in database, so in your model you need to use:
protected $appends = ['review_date_iso'];
but you don't have to include here review_date because it's already in your table in database and your accessor will be automatically fired.
We often have use cases where we only want to update a subset fields on a resource. So if we have a resource Person:
type Person struct {
Age int
Name string
Otherfield string
}
Say the calling client only wants to update the Age field. How would an endpoint be normally set up to handle this?
I believe this should be done with a PATCH request, with only the fields being set as part of the payload, ie:
{
Age: 21
}
However, this won't work with proto3 because as far as I know there are no null fields, only default values. This won't work in many cases where the default value is valid.
Looking at Google own protobuf files (e.g. here), they use FieldMask for partial update.
FieldMask object is passed along with the request, and has the form (in JSON):
{
mask: "Person.Age"
}
This allows the client to tell the server which fields they wish to update, without counting on the partial message itself to figure this out.
I think this adds unnecessary complexity on (each!) client, but we couldn't find any other way to achieve partial updates with proto3.
You can see full documentation of FieldMask here.
Note that it can also be used to filter out responses if the client doesn't need the entire object.
I'm writing a Joomla 2.5 or 3.x component
which make data elaboration and returns some data.
I want that work as a service that is invoked and returns data
(eg
I call www.mysite.com?option=com_mycomponent&view=myview
and result for example my json data ..or xml or what i need after my elaboration
)
so i need that my output view is raw.
i need no template and no css or js..
only my result..
but now the results are inserted into the template
Is it possible?...
I tried to create a RAW mode in my template
like Here .
this works but is not what I want
but it is a dirty solution
because it work if the url i have to call is like ...
www.mysite.com~....~&tmpl=raw
I'd like my component can output as raw.
Thanks
Create RAW view views/[myview]/view.raw.php inside your component
In requests require RAW format
index.php?option=com_mycomponent&view=myview&format=raw.
Like in com_banners/views/tracks/view.raw.php.
Sames goes for JSON and XML.
Here's a list of generic document formats: libraries/joomla/document
feed
html
image
json
opensearch
raw
xml
To use JSON format in response, I recommend new JResponseJson class:
// Anything that may be serialized with json_encode or an Exception
$data = array('some' => 'data');
echo new JResponseJson($data);
Is it possible to have the Help Page sample generator ignore certain properties of a particular type?
For example, we use the same DTO for object Request and Response messages, for both POST and PUT requests. When user is POSTing a model (creating a new record) they don't need to provide the ID field.
But once its created and we serialize the new record into the response body, the ID field is included and returned to the client.
So in the POST request sample, I don't want the ID field to be displayed because for post request it doesn't make sense.
But the POST response sample, I do want the ID field displayed...
I am aware that there is the ApiExplorerSettings attribute which can be applied to a Class or Method...but is there anything similar for a Property?
Something like this would be great:
public class MyDTO
{
[ApiExplorerSettings(IgnoreForRequestApi = true, IgnoreForResponseApi = false)]
public int Id { get; set; }
// Other properties omitted for brevity...
}
Using the following annotation I've successfully hidden a property from the generation!
[ApiExplorerSettings(IgnoreApi = true)]
No, there isn't a similar option for a property. HelpPage uses formatter instances configured on the application to serialize the samples and as you can imagine the formatters must not have this knowledge within themselves.
Regarding workarounds:
a. You could explicitly set the raw sample for a particular action's requestsample via the SetSampleRequest extension of HttpRequestMessage. You should be able to see some examples about this in the file at *Areas\HelpPage\App_Start\HelpPageConfig.cs*.
b. In the file Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs, there is a method called WriteSampleObjectUsingFormatter which uses the application's formatter instances to write the samples. Here you would need to create new formatter instances having similar settings as your normal application has(so that they reflect the exact serialization/deserialization semantics that your application would normally react to when actual requests are made) and then try to hide the properties which you want to. We want to create new instances because we do not want to disturb the normal functioning of the application.
Example: In case of Json, you could create a new Json formatter instance and provide a ContractResolver which can hide the properties. Check this link: http://james.newtonking.com/projects/json/help/html/ConditionalProperties.htm
In case of Xml, I am not sure how we can hide properties without using the IgnoreDataMember attribute and also being non-intrusive.
Currently I would prefer option 'a' as its comparatively a simple workaround than 'b'.
ASP.NET WEB API uses Json.NET for JSON and DataContarctSerailizer for XML formatting so if you add [JsonIgnore] annotations over properties that you do not want included in your serialization should work just fine.
I have a MVC 3 project that uses Entity Framework. I can successfully update entities like this:
[HttpPost]
publiv RedirectResult Update(MyEntity entity)
{
if(ModelState.IsValid)
{
this.entityRepository.Update(entity);
return RedirectResult(".../Admin");
}
return RedirectResult(".../UnssuccessfullOperation");
}
Now the problem arised when I added DateTime property to my entities. If I do not add the #Html.HiddenFor for my DateTime property the date of my entity is 01.01.0001 (or DateTime.Min), which obviously cannot be saved to the database. If I add the hidden input the date is rendered but on update my ModelState is not valid and I guess this is due to the fact that the datetime is passed as a string.
Now there is one solution, but it seems a little strange - to not render Html.Hidden in the view and to use the datetime from the entityRepository like this:
entity.DateSomething = this.entityRepository.GetSingle(entity.ID).DateSomething;
but it does not seem very correct. Are there any other better options in that case?
If I add the hidden input the date is rendered but on update my
ModelState is not valid and I guess this is due to the fact that the
datetime is passed as a string.
No, I suspect that it's due to the culture setting in your application and the datetime format used in the hidden field. They probably don't match.
Take a look at the following blog post which covers the different issues that arise when parsing dates and how the format will depend on whether you are doing a GET or POST request and also a possibility to write a custom model binder to use a fixed format for dates.