combine the array inside object using the spread operator - ecmascript-6

let color = ["blue", "red", "yellow" , "green"]
let dataAdditionalBook= {
Author: "John Doe",
PublishYear: 2020
}
let book = {
Name: "basic programming",
NumberOfPages: 172,
CoverColor:["black"]
}
// the above code should not be changed or deleted at all
/* Write the answer code here */
combine the color variable (combine with the CoverColor attribute) and the dataAdditionalBook into the book variable using the spread operator

As you want to store updated values in book object here you go:
let color = ["blue", "red", "yellow", "green"];
let dataAdditionalBook = {
Author: "John Doe",
PublishYear: 2020,
};
let book = {
Name: "basic programming",
NumberOfPages: 172,
CoverColor: ["black"],
};
book.CoverColor = [...book.CoverColor, ...color];
book = Object.assign(book, dataAdditionalBook);
console.log(book);

first you can combine book CoverColor with with the color
const bookWithNewColor = {...book,CoverColor:[...book.CoverColor,...color]} //updated code here
after that combine bookWithNewcolor and dataAdditionalBook
const newBook = {...bookWithNewColor,...dataAdditionalBook}
console.log(newBook)
the result:
{
name: 'basic programming',
NumberofPages: 172,
CoverColor: [ 'black','blue', 'red', 'yellow', 'green' ],
Author: 'John Doe',
Publish_year: 2020
}

Related

How to filter JSON data by URL parameter?

Lets say if I am looking to filter by id=2 in the browser's URL. This is currently not working (retrieving all the data instead):
/stories?id=2
This is my json file:
{
"stories": [
{
"id": 0,
"title": "Puss In Boots",
"subtitle": ""
},
{
"id": 1,
"title": "Aladdin",
"subtitle": ""
},
{
"id": 2,
"title": "Sleeping Beauty",
"subtitle": ""
},
{
"id": 3,
"title": "Puppy Dreams",
"subtitle": ""
}
]
}
(if you need vanilla js only, here is the solution)
I create a simple function that gets the ID from the URL, then access the correct id in JSON, and shows the title inside a div.
change the ?id= to see the changes
const data = {
stories: [{
id: 0,
title: "Puss In Boots",
subtitle: "",
},
{
id: 1,
title: "Aladdin",
subtitle: "",
},
{
id: 2,
title: "Sleeping Beauty",
subtitle: "",
},
{
id: 3,
title: "Puppy Dreams",
subtitle: "",
},
],
};
const card = document.getElementById("card");
setText(data, card);
function setText(data, element = document.body) { // element if there isn't then we get the body instead
const id = getUrlParams().id ?? 0; // if url is ?id=2 then it will return 2, if undefined then 0
const base = data.stories[id]; // change this if the structure is different or changed.
myAppLogic();
function myAppLogic() { // put here all your logic
element.textContent = base.title;
}
}
function getUrlParams() {
let result = []; // [] empty array at the start
const stringArray =
location.search // "?id=number&other=string&another=string" , this get the last part of the URL
.substring(1) // delete the "?" character from the location.search
.split("&"); // ["id=number", "other=string", "another=string"]
stringArray.forEach((string) => {
result.push(
string.split("=")
);
}); // [[id, number], [other, string], [another, string]]
return Object.fromEntries(result); // {id: number, other: string, another: string}
}
#card {
background: #ccc;
padding: 1rem;
border-radius: 0.5rem;
text-align: center;
}
<div id="card"></div>

How to group suggestions nested list in the primeng autocomplete angular 8

I am trying to group the autocomplete suggestions and would like to render them in primeng.
How we can add a custom template in primeng?
my data
data = [{"id":"m1","name":"menu1","val":"D","items":[{"id":"d1","name":"datanested1","val":"D","items":[{"id":"1","name":"direct Data","val":"E"},{"id":"2","name":"test","val":"E"}]}]},{"id":"d2","name":"menu2","val":"D","items":[{"id":"21","name":"test21","val":"E"},{"id":"22","name":"test23","val":"E"}]},{"id":"d3","name":"menu3","val":"D","items":[{"id":"31","name":"test data 3","val":"E"},{"id":"32","name":"test data 4","val":"E"}]}]
Is there any other libraries available in angular 8 which support this?
I would like to achieve something like this when users start searching in autocomplete...
Menu1 - header
datanested1 -subheader
direct Data -values
test -values
Menu2 - header
test21-values
test23-values
Menu3 - header
test data 3-values
test data 4-values
1. if the user types "direct" in the input box...
Menu1 - header
datanested1 -subheader
direct Data -values
2. if the user types "data" in the input box...
Menu3 - header
test data 3-values
test data 4-values
3. if the user types "menu" in the input box...
Menu1 - header
datanested1 -subheader
direct Data -values
test -values
Menu2 - header
test21-values
test23-values
Menu3 - header
test data 3-values
test data 4-values
I have tried the following example in stackblitz.
https://stackblitz.com/edit/primeng-7-1-2-qtsnpm
In the below approach we will reduce the array to a simple structure
[
{
"id": "m1",
"name": "menu1",
"val": "D",
"search": ["m1", "d1", "1", "2", "menu1", "datanested1", "direct Data", "test"],
"depth": 2
},
{
"id": "d1",
"name": "datanested1",
"val": "D",
"search": ["d1", "1", "2", "datanested1", "direct Data", "test"],
"depth": 1
},
{
"id": "1",
"name": "direct Data",
"val": "E",
"search": ["1", "direct Data"
],
"depth": 0
},
...
]
The idea is this, we will use the depth to format out text while the search for searching.
maxDepth = 0;
reducedArray = (arr, depth = 0, parentSearch = []) => {
this.maxDepth = Math.max(this.maxDepth, depth);
if (!arr) {
return [];
}
return arr.reduce((prev, { items, ...otherProps }) => {
// const depth = this.findDepth({ items, ...otherProps });
const search = [
...this.getProps({ items, ...otherProps }, "id"),
...this.getProps({ items, ...otherProps }, "name")
];
const newParentSearch = [...parentSearch, otherProps.name, otherProps.id];
return [
...prev,
{ ...otherProps, search, depth, parentSearch },
...this.reducedArray(items, depth + 1, newParentSearch)
];
}, []);
};
getProps = (item, prop) => {
if (!item.items) {
return [item[prop]];
} else {
return [
item[prop],
...item.items.map(x => this.getProps(x, prop))
].flat();
}
};
We can apply styles like below
getStyle(depth) {
return {
color: depth === 0 ? "darkblue" : depth === 1 ? "green" : "black",
paddingLeft: depth * 7 + "px",
fontWeight: 800 - depth * 200
};
}
I will use reactive programming so I will convert the object to an Observable usinf of operator
data$ = of(this.reducedArray(this.data));
filteredData$ = combineLatest([this.data$, this.filterString$]).pipe(
map(([data, filterString]) =>
data.filter(
({ search, parentSearch }) =>
!![...search, ...parentSearch].find(x => x.includes(filterString))
)
)
);
We now done, the remaining is to update html
<p-autoComplete [(ngModel)]="cdsidvalue" [suggestions]="filteredData$ | async"
(completeMethod)="filterString$.next($event.query)" field="name" [size]="16" placeholder="Menu" [minLength]="1">
<ng-template let-menu pTemplate="item">
<span
[ngStyle]="getStyle(menu.depth)" >{{ menu.name }}</span>
</ng-template>
</p-autoComplete>
Demo Here
Update
Since we are using reactive programming, refactoring to accept http requests is quite easy, simply replace the observable with an http request
data$ = this.http.get<any[]>("my/api/url");
filteredData$ = combineLatest([this.data$, this.filterString$]).pipe(
map(([data, filterString]) =>
this.reducedArray(data).filter(
({ search, parentSearch }) =>
!![...search, ...parentSearch].find(x => x.includes(filterString))
)
)
);
See this update in action
I have also updated the html to add loading message, we do not want to display a form without data
Patel , Yes you can add Group Header in NgPrime
.ts
adminentrylistSearch = [
{
Grp_Header:'THIS IS Header 1' ,
cdsid: "0121",
firstname: "FirstName1",
lastname: "LastName1",
fullname: "LastName1, FirstName1"
},
{
cdsid: "0122",
firstname: "FirstName1",
lastname: "LastName2",
fullname: "LastName2, FirstName2"
},
{
cdsid: "0123",
firstname: "FirstName3",
lastname: "LastName3",
fullname: "LastName3, FirstName3"
},
{
Grp_Header:'THIS IS Header 2',
cdsid: "0124",
firstname: "FirstName4",
lastname: "LastName4",
fullname: "LastName4, FirstName4"
},
{
cdsid: "0125",
firstname: "FirstName5",
lastname: "LastName5",
fullname: "LastName5, FirstName5"
},
{
cdsid: "0126",
firstname: "FirstName6",
lastname: "LastName6",
fullname: "LastName6, FirstName6"
},
{
cdsid: "0127",
firstname: "FirstName7",
lastname: "LastName7",
fullname: "LastName7, FirstName7"
}
];
.html
<p-autoComplete [(ngModel)]="cdsidvalue" [suggestions]="filteredCountriesSingle" [dropdown]="true"
(completeMethod)="filterCountrySingle($event)" field="firstname" [size]="16" placeholder="CDSID">
<ng-template let-adminentrylistSearch [ngIf]="adminentrylistSearch.index" pTemplate="text">
<div class='unclickable-header'>
<span [style.font-weight]="adminentrylistSearch.Grp_Header ? 'bold' : null"> {{adminentrylistSearch.Grp_Header ? adminentrylistSearch.Grp_Header : adminentrylistSearch.firstname}} </span>
</div>
</ng-template>
</p-autoComplete>
Check Result here...
Demo
In your primeng version (7.1.2) grouped autocomplete is not supported. But it's supported in latest version(11.3.0). Please see below image and follow https://www.primefaces.org/primeng/showcase/#/autocomplete

Echarts - Dynamic multi line chart based on Json data

I am trying to plot time line chart with multiple lines (number of lines is dynamic based on Json data). I am getting Json data as mentioned. I would like to have each line plotted for each product. How should I convert data so that echarts supports?
[
{date: "2019-05-21 00:00:00 UTC", value: 100, product: 'p1'},
{date: "2019-05-21 00:00:00 UTC", value: 50, product: 'p2'},
{date: "2019-05-19 00:00:00 UTC", value: 200, product: 'p3'},
{date: "2019-05-18 00:00:00 UTC", value: 70, product: 'p1'},
{date: "2019-05-18 00:00:00 UTC", value: 125, product: 'p2'},
{date: "2019-05-18 00:00:00 UTC", value: 55, product: 'p3'}
]
You should be storing your axis data separately from your values, in a simple multi-line chart: see the following two examples:
https://echarts.baidu.com/echarts2/doc/example/line1.html#-en
https://echarts.baidu.com/echarts2/doc/example/line8.html#-en
The second example provides the "time" x-axis type, which we can use with the first, which provides a good multi-line framework.
Your option may look something like this:
option = {
title : {
text: 'Multi-line Time Axis example',
subtext: 'made for Dileep'
},
tooltip : {
trigger: 'axis'
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
xAxis : [
{
type : 'time',
}
],
yAxis : [
{
type : 'value',
axisLabel : {
formatter: '{value} $'
}
}
],
series : [
{
name: 'series1', // Product p1, for instance
type: 'line',
data: (function () {
var d = [];
var len = 0;
var now = new Date();
var value;
while (len++ < 10) {
d.push([
new Date(2014, 9, 1, 0, len * 10000), // some Date() object
(Math.random()*30).toFixed(2) - 0// // some random value
]);
}
return d;
})()
},
{
name: 'series2', // product p2
type: 'line',
data: (function () {
var d = [];
var len = 0;
var now = new Date();
var value;
while (len++ < 10) {
d.push([
new Date(2014, 9, 1, 0, len * 10000),
(Math.random()*30).toFixed(2) - 0,
]);
}
return d;
})()
}
]
};

How to select some properties in JSON

Here is the data:
var data1 = [{
"Date": "2016-07-09",
"H1_PNL2": 20,
"H1_NAV2" : 20
"H2_PNL2": 20,
"H2_NAV2" : 20,
"NAV": 26.28,
"PNL": 7.61
}, {
"Date": "2016-07-10",
"H1_PNL2": 20,
"H1_NAV2" : 20
"H2_PNL2": 20,
"H2_NAV2" : 20,
"NAV": 27.55,
"PNL": 12.89
}];
If I only want to select Date and H2_PNL2 i.e
var data1 = [{
"Date": "2016-07-09",
"H2_PNL2": 20,
}, {
"Date": "2016-07-10",
"H2_PNL2": 20,
}];
How to select the specific properties I want?
Use Array.prototype.map to iterate through your array, then for each object construct a new object with just the properties that interest you:
data1.map(o => ({ Date: o.Date, H2_PNL2: o.H2_PNL2 }));
EDIT: Deleting properties can go two ways, depending on if you want to preserve the original or not.
Destructive:
data1.forEach(o => { delete o.NAV; delete o.PNL; });
Non-destructive:
data1.map(o => {
var c = Object.assign({}, o);
delete c.NAV; delete c.PNL;
return c;
});

Getting json object data with react

I am attempting to pull data out of json like this, which is imported as "values"
{
"content": {
"person": [
{
"name": "Test"
"age" : "24:
}
]
}
}
I am using .map like below but getting the error .default.map is not a function I believe it is because i have objects not arrays, i've tried a bunch of stuff including object.keys but i'm getting errors all over the place, any direction would be appreciated.
import values from './sample.json'
const vals = values.map((myval, index) => {
const items = person.items.map((item, i) => {
return (
<div>{item.name}</div>
)
})
return (
<div>{items}</div>
)
})
I think your data and code have some errors. But after fixing those and also changing the name from 'person' to 'people' if that's what you are after, here's the code that does what you are trying to do:
var data = {
content: {
people: [
{
name: "Test",
age: 24,
},
{
name: "Foo",
age: 25,
},
],
},
};
var App = React.createClass({
render: function () {
var people = data.content.people.map(function (person) {
return <div>{person.name}</div>;
});
return <div>{people}</div>;
},
});
ReactDOM.render(<App />, document.getElementById("app"));
And here's the JSBin for that: https://jsbin.com/coyalec/2/edit?html,js,output
Update: I'm updating the answer with more detailed example. It now deals with data more generically, like it doesn't assume what are the entries of 'contents' and such, but it knows that each type like 'people' or 'pets' are an array.
var data = {
content: {
people: [
{
name: "Test",
age: 24,
},
{
name: "Foo",
age: 25,
},
],
pets: [
{
name: "Sweety",
age: 3,
},
{
name: "Kitty",
age: 5,
},
],
},
};
var App = React.createClass({
render: function () {
// Get the keys in data.content. This will return ['people', 'pets']
var contentKeys = Object.keys(data.content);
// Now start iterating through these keys and use those keys to
// retrieve the underlying arrays and then extract the name field
var allNames = contentKeys.map((t) =>
data.content[t].map((e) => <div>{e.name}</div>)
);
return <div>{allNames}</div>;
},
});
ReactDOM.render(<App />, document.getElementById("app"));
And here's the latest JSBin: https://jsbin.com/coyalec/4/edit?html,js,output