I'm trying to format a JSON date to a JavaScript date to display it in a nice way. The original date comes from a JSON-object, which looks like this:
{
"name": "foo",
"num": "1",
"date": "\/Date(1367539200000)\/"
}
The place where the JSON elements should be displayed later is a SAPUI5 object header:
objectHeader = new sap.m.ObjectHeader({
title: "{/name}",
number: "{/num}",
attributes: [
new sap.m.ObjectAttribute({
text: "{/date}"
})
]
});
Since the JSON object is bound to the object header via
dataModel.setData(json)
objectHeader.setModel(dataModel)
the values are correctly substituted. But i want to have the date correctly formatted to a more readable format instead of seeing /Date(1367539200000)/ on my website. I tried with
new sap.m.ObjectAttribute({
text: new Date(parseInt("{/date}".substr(6))).toLocaleString('de');
})
But that failed with an 'Invalid Date'. What would be the right syntax to format the JSON date to a Javascript data object in a model binding?
You can use a formatter to do that for you. The advantage is that you can properly use databinding, so your controls will be updated automatically in case the model changes.
new sap.m.ObjectAttribute({
text: {
parts: [
{path: "/date"}
],
formatter: function(date){
//do whatever you want
return /* the value you want to have as result */;
}
}
})
Related
Model:
const fooSchema = new mongoose.Schema({
fooCreationDate: {
type: Date
},
bar: [{
barCreationDate: {
type: Date
}
}]
});
const foo = mongoose.model(`foo`, fooSchema);
If we want to search for foo objects that were created between 2022-01-01 and 2022-01-02, we can use the following mongoose query:
foo.find({
fooCreationDate: {
$gte: "2022-01-01T00:00:00.000",
$lt: "2022-01-02T00:00:00.000"
}
});
Please note that I'm using strings instead of date objects. The reason is that the query is passed by the client through an AJAX call with dataType: "jsonp". Every date object that is passed like that to the backend is automatically converted to an ISO string. Despite that, the query works without any issues - the find function automatically parses dates represented as ISO strings.
We'd now like to extract every bar object that was created in the same time range, so we'll need to use an aggregation:
foo.aggregate([{
$unwind: `$bar`,
}, {
$match: {
"bar.barCreationDate": {
$gte: "2022-01-01T00:00:00.000",
$lt: "2022-01-02T00:00:00.000"
}
}
}]);
Unfortunately, nothing is found despite the fact that the database contains matching bar objects. This can be confirmed by passing Date objects instead of strings to the $match aggregation:
foo.aggregate([{
$unwind: `$bar`,
}, {
$match: {
"bar.barCreationDate": {
$gte: new Date("2022-01-01T00:00:00.000"),
$lt: new Date("2022-01-02T00:00:00.000")
}
}
}]);
This query returns some results, so the conclusion is that mongoose accepts ISO date strings in the find function, but can't handle them in the aggregate function.
Is there any known workaround? I could, for example, deep-scan every query object passed from the client and search for ISO date strings, then convert them to Date objects, but that's a bit dirty in my opinion. I'm using mongoose v5.6.4 and mongodb v4.2.2.
I have the following JSON string that I would like to extract the date and the time from:
{ "id": 1, "time": { "date": "2019-06-12 11:51:22.000000", "timezone_type": 3, "timezone": "UTC" }, "productCategory": "some cat", "kitchen": { "house": { "id": 555, "name": "bigHouse" }, "id": 55, "name": "smallKitchen", "country": "US" } }
I do it currently like this:
<tr v-for="(cabinet, i) in cabinets">
<td>{{ cabinet.kitchen.id }}</td>
<td>{{ cabinet.productCategory }}</td>
<td>{{ getDate(cabinet.time.date) }}</td>
<td>{{ getTime(cabinet.time.date) }}</td>
</tr>
<script>
const axios = require('axios');
export default {
name: "Cabinets",
data() {
return {
bedroom : this.$session.get('bedroom').id,
cabinets: []
}
},
mounted() {
axios({
method: 'GET',
url: `/bedroom/${this.bedroom}/cabinets`
})
.then(response => {
this.cabinets = response.data
})
},
methods: {
getDate(datetime) {
return new Date(datetime).toISOString().slice(0,10);
},
getTime(datetime) {
return new Date(datetime).toISOString().slice(11,19);
}
}
}
</script>
The date works fine but the time doesn't. The date and time are retunred as follows respectivly: 2019-06-12 and 09:51:22. The time should have been 11:51:22. This is probably becasue I'm using the method Date() when trying to get the time but when I tried using Time() it gave an error:
[Vue warn]: Error in render: "ReferenceError: Time is not defined".
I, however, even if I could find a really simple fix for the time, really don't like this way with slicing and was searching for methods that does do this for me, because as you can see, slicing the string is malfunctioning already.
The reason you're getting that error is because there's no Time object in JavaScript.
A somewhat more robust method is Date's toLocaleTimeString().
You can use it in your getTime() method: new Date(dateTime).toLocaleTimeString().
Note that toLocaleTimeString() will display the time as specified by the user's machine's culture.
You can override this behavior, though.
In short, no. Dates are notorious for being a bother to work with. I believe the most popular package is Moment.js. Ensure you store the dates to your database in standard ISO format, and then modify the dates on the front end after you pull them from the database.
The "right" format for dates in JSON is ISO. I don't recognise your time object. Is it a standard format? In any case, because it's UTC, you can easily create an ISO date with string methods, parse it with the built-in Date object, then use toLocaleTimeString to format it. To parse, do this...
new Date(time.date.replace(" ","T") + "Z").toLocaleString({},{timeZone:"UTC"})
.toLocaleDateString()
.toLocaleTimeString()
Beware, don't just take your date string and feed it to the Date object. The timezone is not specified, so the parser might or might not assume it's a local datetime. The Z on the end of the iso string instructs the parser that it's UTC, which is what it says in your json.
I have this in my console chrome:
[{"id":40,"endDate":"2017-04-22","dataA":"2017-04-19","nrC":2,"type":"CO","dataD":"2017-04-19","startDate":"2017-04-20"},{"id":40,"endDate":"2017-04-26","dataA":"2017-04-26","nrC":4,"tyoe":"CP","dataD":"2017-04-23","startDate":"2017-04-25"},
This json string is comming from the servlet that calls DAO class to take the information from db.
So, this string is (dynamically) passed into a jsp page from request session...and i put it into var DAYS = '${jsonArrayString}'; then console.log(DAYS); then it prints that json string above.
So...it can print more data then two.
It has to be put into a javascript variable loke this:
var DAYS = '${jsonArrayString}'; //That's what's on my console..and it comes from session into this jsp page
I think it has to be iterated through a foreach and print it in that format.
var USER_DAYS = [
{
id: value from jsonArrayString,
date: value from jsonArrayString,
title: value from jsonArrayString,
start: new Date(value from jsonArrayString),
end: new Date(value from jsonArrayString),
allDay: true,
className: 'done'
},
];
I tried to put the values manually and it works...like this:
var USER_DAYS = [
{
id: 1,
date: '2017-04-05',
title: 'CO',
start: new Date(2017, 3, 5),
end: new Date(2017, 3, 7),
allDay: true,
className: 'done'
},
I don't know hot to put the values from that json string(
Which can be anythong ... more than 2 records)...that why I need to iterate through that json string.
I want the values to be put only in that format, in that variable (var USER_DAYS)
I tried somthing like this, but it does't work:
<c:forEach items="${jsonArrayString}" var="jsonArrayString">
{
id: '${jsonArrayString.nrC}' ,
date: '${jsonArrayString.dataD}' ,
title: '${jsonArrayString.type}' ,
startDate: '${jsonArrayString.startDate}',
endDate: '${jsonArrayString.endDate}',
allDay: true,
className: 'done'
},
</c:forEach>
];
or like this:
var USER_DAYS = [
{
id: DAYS.nrC,
date: DAYS.dataD,
title: DAYS.type,
start: new Date(DAYS.startDate),
end: new Date(DAYS.endDate),
allDay: true,
className: 'done'
},
];
How to do this?
try parse to json string into json objects.
Example
var USER_DAYS = JSON.parse('${jsonArrayString}')
JavaScript code runs only on the client side, while JSP on the server. You cannot iterate over the JavaScript variable while the page is rendered at the server.
If you want to serve a page that already contains the data, you should pass the data to the JSP page as a model attribute. To do this, take a look at this post.
If you want to populate the page with data after it has been loaded to the browser, you have to use a JavaScript library, such as jQuery. In this case, you have to send a request to the server to get the data in JSON format, and then you can manipulate them on the client side.
I want to build my own formattor for displaying the amount as it should in the different currencies.
One could guess I use this solution I already know:
<t:template>
<Text text="{
parts: [
{path: 'amount'},
{path: 'currency'}
],
type:'sap.ui.model.type.Currency',
formatOptions: {
currencyCode: false
}
}"
</t:template>
the problem with this solution is I already show the currency in a seperate column and if I go with this solution it looks pretty ugly....
so I tried this one:
<t:template>
<Text text="{parts: [
{path: 'amount'},
{path: 'currency'}
],
formatter : '.formatter.currency'}"
/>
</t:template>
and my formatter function looks like this:
currency: function(amount, currency) {
var change = [];
change.push(amount);
change.push(currency);
var sInternalType = "";
var amount1 = new sap.ui.model.type.Currency();
amount1.formatValue(change, sInternalType);
return amount1;
}
Here I would guess I do something completely wrong, as English is not my first language I would probably assume I didnt understood the API References right, as they is stated this:
formatValue(vValue, sInternalType): any
Format the given array containing amount and currency code to an output value of type string. Other internal types than 'string' are not supported by the Currency type. If an source format is has been defined for this type, the formatValue does also accept a string value as input, which will be parsed into an array using the source format. If aValues is not defined or null, null will be returned.
Parameters:
{array|string} vValue the array of values or string value to be formatted
{string} sInternalType the target type
Returns:
{any} the formatted output value
If it is your intention not to show the currency symbol or code because you already show it elsewhere, you could simply set showMeasure to false, e.g.:
<Text xmlns:core="sap.ui.core"
core:require="{ CurrencyType: 'sap/ui/model/type/Currency' }"
text="{
parts: [
'amount',
'currency'
],
type: 'CurrencyType',
formatOptions: {
showMeasure: false
}
}"
/>
Not showing the currency code/symbol is a feature of the standard Currency type. You don't need to extend it.
Note: In case of OData V4, require the type sap/ui/model/odata/type/Currency instead.
If you want to use an custom formatter, you can define it in this way:
currency: function(amount, currency) {
var oCurrency = new sap.ui.model.type.Currency({
showMeasure: false
});
return oCurrency.formatValue([amount,curreny], "string");
}
But I would recommend to use the solution from jpenninkhof for your use case
I'm using the jQuery data() function to store data on a series of divs in a format similar to:
{
options: {
example: {
option_1: {
value: "example 1"
},
option_2: {
value: "example 2"
}
}
}
}
I can add new keys and update the data, e.g.
$("#mydiv").data('options',{'example':{} }); // the object is already created in the live version
$("#mydiv").data('options')['example']['option_3'] = { value: "example 3" };
But when I come to use removeData(), FireBug tells me that the key is undefined, e.g.
$("#mydiv").removeData('options')['example']['option_2'];
Any help appreciated!
.removeData(name) removes the previously stored data with the given name, and returns a jQuery object. In your scenario, you don't want the remove the entire options object, just a specific property of it, so you should be using delete instead:
delete $("#mydiv").data('options')['example']['option_2'];