Moment JS ("Must to show days in next week") - javascript

I'm working on a weather service and I need to write a code for showing the weather forecast for next week. From the server, I only have a "time" entity with "value" of next Monday like "2020-04-06T00:00:00.000+02:00".
{
"message": "Show me the weather for next week",
"entities": [
{
"value": "weather",
"text": "weather",
"entity": "radio_tag"
},
{
"value": "play_next",
"text": "next",
"entity": "media_control"
},
{
"value": "next",
"text": "next",
"entity": "next"
},
{
"value": {
"values": [
{
"value": "2020-04-06T00:00:00.000+02:00",
"grain": "week",
"type": "value"
}
],
"value": "2020-04-06T00:00:00.000+02:00",
"grain": "week",
"type": "value"
},
"entity": "time"
},
{
"value": "weather_condition",
"entity": "sub_intent"
}
],
"intent": "weather_condition",
"user_id": "5258",
"language_id": "56",
"driver": "gigaaa",
"abort": "0",
"extras": {
"coordinates": {
"lat": "44.4150804",
"lng": "19.1290729"
}
},
"conversation_messages_count": "1"
}
For example, if today is Tuesday, I must show Monday and Tuesday for next week, if today is Saturday (04.04), I must show every day from Monday (06.04) to Saturday(11.04) for next week. I am a beginner and I must use Moment JS for this.
I tried this condition if (this.conversation.payload.grain === 'week' && moment().startOf('isoWeek').isSame(this.conversation.payload.forecastTime))
but the second part of condition is not correct.

We take the current date and check if we aren't in the same isoweek as the data in order to filter out data rows from the current week. We then take the current date and add a week so we can check that <1 week has passed.
Theoretically, as long as the timezone of the user and the returned data are the same, it should be what you need.
var valueFromData = this.conversation.payload.value;
var dateFromData = moment(valueFromData).startOf('day');
var oneWeek = moment().add(7,'d').startOf('day');
if(moment().startOf('isoweek').isBefore(dateFromData)
&& dateFromData.isBefore(oneWeek))

Related

Is there a way to display more than 5 buttons in Amazon lex-v2 response

This is my sessionState object
{
"sessionAttributes": {},
"dialogAction": {
"type": "ElicitSlot",
"slotToElicit": "flowName"
},
"intent": {
"name": "WelcomeIntent",
"confirmationState": "None",
"slots": {
"flowName": null
},
"state": "Fulfilled"
}
this is messages array
[
{
"contentType": "ImageResponseCard",
"content": "Some content",
"imageResponseCard": {
"title": "Choose option",
"subtitle": "options are",
"buttons": [
{
"text": "option1",
"value": "option1"
},
{
"text": "option2",
"value": "option2"
},
{
"text": "option3",
"value": "option3"
},
{
"text": "option4",
"value": "option4"
},
{
"text": "option5",
"value": "option5"
},
{
"text": "option6",
"value": "option6"
},
{
"text": "option7",
"value": "option7"
}
]
}
}
]
iam sending 7 buttons from lamda function, but lex is not accepting more than 5 buttons. It is giving error saying buttons should be between 0,5 index. Is there way to display more than 5 buttons in lex response.
As per the developer guide, ImageResponseCard supports a maximum of 5 button objects.
Array Members: Minimum number of 0 items. Maximum number of 5 items.
ImageResponseCard - AWS Lex V2 Developer Guide
I took the approach of conditionally eliciting different cards after a previous slot. In my case, choose a risk level (High, Medium, Low) and depending on which value, elicit either a High, Med, or low slot card prompt. Just a workaround.

PouchDB Grouping and Summarizing

I am using pouchdb and have a document structure like this:
{
"_id": "1",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": "2"
},
{
"date": "2016-09-16 00:00:00",
"qty": "3"
}
],
"salesy": [
[
{
"date": "2016-09-15 00:00:00",
"qty": "1"
}
]
]
}
},
"_rev": "rev"
}
I now want to get something like this as a result from pouchdb:
{
"_id": "1",
"title": "Title",
"categories": {
"category1": {
"salesx": 2 + 3 = 5,
"salesy": [
[
{
"date": "2016-09-15 00:00:00",
"qty": "1"
}
]
]
}
},
"_rev": "rev"
}
So, salesx should be grouped and the qty should be summarized.
salesy should not be changed.
I also want to add a where clause to the date field.
I tried to start with a map function which selects the correct dates. But I don't know what to emit to group the qty later.
function myMapFunction(doc) {
doc.categories.forEach(category => {
category.salesx.forEach(salex => {
if (salex.date >= mydate) {
emit(?)
}
})
})
}
I can't find a good example on pouchdb docs. They only provide examples for grouping multiple documents together.
Does anyone know how I can achieve grouping the document?
I modified the documents like below, to convert the qty field from string values to number values, to be able to do math operations:
{
"_id": "sale0000",
"_rev": "2-5cd6fff48f9fd099481d3b523ff1191f",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": 2
},
{
"date": "2016-09-16 00:00:00",
"qty": 3
}
],
"salesy": [
[
{
"date": "2012-09-15 00:00:00",
"qty": 1
}
]
]
}
}
}
As you mentioned in the comments:
All documents look exactly like the one I already showed. Except the
number of entries in salesx and the number of categories (e.g.
category1, category2 ...) is modified
Based on your above statement, I created in my sample database some documents with varying number of entries in salesx and varying number of categoiry1, category2, etc., but each salesy has only one entry.
Here is another one of my sample documents:
{
"_id": "sale0002",
"_rev": "3-12bf5c872fc124c1f0a5a4a108cb4f7a",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": 2
},
{
"date": "2016-09-16 00:00:00",
"qty": 3
},
{
"date": "2017-10-16 00:00:00",
"qty": 9
}
],
"salesy": [
[
{
"date": "2014-09-15 00:00:00",
"qty": 1
}
]
]
},
"category2": {
"salesx": [
{
"date": "2018-01-15 00:00:00",
"qty": 2
},
{
"date": "2012-08-16 00:00:00",
"qty": 3
},
{
"date": "2015-10-16 00:00:00",
"qty": 7
}
],
"salesy": [
[
{
"date": "2011-03-15 00:00:00",
"qty": 1
}
]
]
}
}
}
I'm not sure if I understand what exactly you intend, but I developed the following view map function:
function (doc) {
if(doc.categories){
for(var categ in doc.categories){
var salesx_qty_sum=0;
for(var i=0, len=doc.categories[categ].salesx.length; i<len; i++){
salesx_qty_sum += doc.categories[categ].salesx[i].qty
}
emit(
doc.categories[categ].salesy[0][0]['date'], //emit the date of salesy as the key
//my understanding is that you need to index/sort
//according to date of salesy
[
salesx_qty_sum, //emit the sum of qty for salesx as value
doc.categories[categ].salesy[0][0]['qty'] //emit qty for salesy (unchanged) as value
]
);
}
}
}
In my sample database I created four documents like yours with different number of entries in salesx and also varying number of categories. There is only one entry inside each salesy:
$ curl -k -X GET 'https://admin:****#192.168.1.106:6984/sample/_all_docs'
{"total_rows":53,"offset":0,"rows":[
...
...
{"id":"_design/by_date","key":"_design/by_date","value":{"rev":"20-04cb881624aa819dac13f69c688f2124"}},
...
...
{"id":"sale0000","key":"sale0000","value":{"rev":"2-5cd6fff48f9fd099481d3b523ff1191f"}},
{"id":"sale0001","key":"sale0001","value":{"rev":"2-e8ee019fb0ad076b82d3f4772f736559"}},
{"id":"sale0002","key":"sale0002","value":{"rev":"3-12bf5c872fc124c1f0a5a4a108cb4f7a"}},
{"id":"sale0003","key":"sale0003","value":{"rev":"2-6d40368ddd16b9d02b908ea95d061c7e"}}
]}
The above view map (named by_date) is indexing my documents like below, in which the key is the date of salesy. Based your description, I assume there should be only one entry in each salesy in each category. Also, the value below is an array in which first element is sum of qty for salesx, and the second element is unchanged qty of salesy:
$ curl -k -X GET 'https://admin:admin#192.168.1.106:6984/sample/_design/by_date/_view/by_date'
{"total_rows":6,"offset":0,"rows":[
{"id":"sale0002","key":"2011-03-15 00:00:00","value":[12,1]},
{"id":"sale0000","key":"2012-09-15 00:00:00","value":[5,1]},
{"id":"sale0001","key":"2013-05-20 00:00:00","value":[12,1]},
{"id":"sale0002","key":"2014-09-15 00:00:00","value":[14,1]},
{"id":"sale0003","key":"2015-04-15 00:00:00","value":[5,1]},
{"id":"sale0003","key":"2018-04-05 00:00:00","value":[5,1]}
]}
You can query the by_date view with startkey and endkey to get the results between two dates, like this:
$ curl -k -X GET 'https://admin:admin#192.168.1.106:6984/sample/_design/by_date/_view/by_date?startkey="2013"&endkey="2015"'
{"total_rows":6,"offset":2,"rows":[
{"id":"sale0001","key":"2013-05-20 00:00:00","value":[12,1]},
{"id":"sale0002","key":"2014-09-15 00:00:00","value":[14,1]}
]}

How to sort array of objects

I need your help to understand how to sort array of objects with another array inside each of object. I have response from api with array bunch of objects like below:
[
{
"name": "[C US Equity] CITIGROUP INC",
"stats": [
{
"label": "DTD",
"value": null
},
{
"label": "MTD",
"value": null
},
{
"label": "YTD",
"value": 0.0536530913792681
},
{
"label": 2016,
"value": 0.18102519526139493
},
{
"label": 2015,
"value": -0.012946569977188238
},
{
"label": 2014,
"value": null
}
]
}...
]
I should be sort it by value of label "YTD" exclude of null value. Any help are welcome
You can use array#sort method
var oldArray = [{
"name": "[C US Equity] CITIGROUP INC",
"stats": [{
"label": "DTD",
"value": null
},
{
"label": "MTD",
"value": null
},
{
"label": "YTD",
"value": 0.0536530913792681
},
{
"label": 2016,
"value": 0.18102519526139493
},
{
"label": 2015,
"value": -0.012946569977188238
},
{
"label": 2014,
"value": null
}
]
}];
oldArray[0].stats.sort(function(a, b) {
return a.label - b.label;
})
console.log(oldArray)
You can use collection sort method provided by lodash. https://lodash.com/docs/4.17.4#sortBy
var users = [{
"name": "[C US Equity] CITIGROUP INC",
"stats": [
{
"label": "DTD",
"value": null
},
{
"label": "MTD",
"value": null
},
{
"label": "YTD",
"value": 0.0536530913792681
},
{
"label": null,
"value": 0.18102519526139493
},
{
"label": "2015",
"value": -0.012946569977188238
},
{
"label": "dtd",
"value": null
}
]
}]
console.log(_.sortBy(users[0].stats, [function(o) { if(o.label){return  o.label.toUpperCase();} }]));
This takes case of null values too.
I think this post may help you.
Take a look of it, it teaches you about how compare works.
All you need to do is to put that JSON thing into an object array,
then compare the value of YTD(make two for-loops, result [i] .stats [j] .label === 'YTD') to make the array to re-order it.
A comparison function is work like below(extracted from the above link)
function CompareNumbers( v1, v2 ) {
if ( v1 < v2 ) return -1; // v1 goes nearer to the top
if ( v1 > v2 ) return 1; // v1 goes nearer to the bottom
return 0; // both are the same
}
when it return -1(or sometimes false), the former one will be pushed to the front of your array, meanwhile 1 or true will push the former one to the back. And 0 (means not true or false, or you can handle the exception by yourself, push back or forward) will happen nothing.
But becare if your array exist two 'YTD' labelled value, if it happens it will make two value to appear in the same data.
This may help you in sorting the data while you cannot directly get a sorted data from your db server.
Oh, forgot to say, the compare function can compare the whole object.(of course you need to extract something like this ---> object[index].['Something your needed']), not only numbers.

Swimlane ngx-charts in Angular2 - Different styles on a single line chart

I have a single line chart, with dates on the X axis. After a certain date,
I would like the line to be a different color. Is this possible using ngx-charts?
Let us assume the date after which you want to change the color as T.
Now you can divide the series into 2 parts
The from start date to T
From T to end date.
And now you can plot the graph using different color for different series
The following data will generate the desired graph.
var data = [
{
"name": "Current",
"series": [
{
"value": 5599,
"name": "2016-09-20T01:04:28.176Z"
},
{
"value": 6247,
"name": "2016-09-20T12:51:24.713Z"
},
{
"value": 4283,
"name": "2016-09-18T15:42:04.800Z"
},
{
"value": 2643,
"name": "2016-09-13T20:10:53.904Z"
},
{
"value": 4105,
"name": "2016-09-18T06:15:10.845Z"
},
{
"name": "2016-09-18T13:08:42.085Z",
"value": 4401
},
{
"name": "2016-09-20T01:04:28.176Z",
"value": 3443
}
]
},
{
"name": "Future",
"series": [
{
"value": 3443,
"name": "2016-09-20T01:04:28.176Z"
},
{
"value": 2604,
"name": "2016-09-20T12:51:24.713Z"
},
{
"value": 2158,
"name": "2016-09-18T15:42:04.800Z"
},
{
"value": 5519,
"name": "2016-09-13T20:10:53.904Z"
},
{
"value": 4532,
"name": "2016-09-18T06:15:10.845Z"
},
{
"name": "2016-09-18T13:08:42.085Z",
"value": 2474
}
]
}
]

Multiline Highchart based on Dates

I want to create a multiline highchart which takes 24hrs in x axis and for each date plot one line.
[{
"date": "2017-05-01T02:50:26",
"value": 764.88
},
{
"date": "2017-05-02T12:29:07",
"value": 978.66
},
{
"date": "2017-05-04T08:30:20",
"value": 522.61
},
{
"date": "2017-05-04T12:29:34",
"value": 762.7
},
{
"date": "2017-05-02T11:09:56",
"value": 809.96
},
{
"date": "2017-05-03T03:32:35",
"value": 736.94
},
{
"date": "2017-05-04T12:56:53",
"value": 339.68
}
]
Here we have 4 unique dates i.e
2017-05-01 , 2017-05-02 , 2017-05-03 , 2017-05-04
and we want four lines of each date. But the x axis has to be hour:minute and y axis is value. I created a fiddle.
To change the way xAxis labels display, you can use Highcharts.dateFormat() function inside xAxis.labels.formatter. Take a look at the example posted below.
API Reference:
http://api.highcharts.com/highcharts/xAxis.labels.formatter
http://api.highcharts.com/highcharts/Highcharts.dateFormat
Example:
http://jsfiddle.net/x41vev1p/

Categories

Resources