Drop down populated from json data - json

I want my drop down to display 2017 and 2018 from my data. 2017 and 2018 repeats a lot throughout my json data file. But I want all the 2017 data to appear when selected and all the 2018 data to be displayed when selected. Currently it shows all data and the drop down is over populated.
I was told to try this but haven't managed to get it to work:
import {DatePipe} from '#angular/common';
.
.
volumes: Volumes[];
years: [] = [];
groupedVolumes : any;
constructor(private volumeService: VolumeService, private router: Router, private datePipe: DatePipe) {
}
ngOnInit(){
this.volumeService.getVolumes().subscribe(volumes => {
this.volumes = volumes;
for(let volume of volumes){
if(this.years.indexOf(datePipe.formatDate(volume.month, 'yyyy')) === -1)
this.years.push(datePipe.formatDate(volume.month, 'yyyy'));
}
this.groupedVolumes = this.group(this.volumes);
this.dataOk = true;
}
}
Html:
<div class="row justify-content-center">
<div class="col-4s">
<p>Financial Year:</p>
</div>
<div class="col-4s">
<select>
<option *ngFor="let year of years">{{ year }}</option>
</select>
</div>
</div>
Json File:
json file:
[
{
"id": 1,
"month": "2017-03-01"
}
{
"id": 2,
"month": "2017-04-01"
}
{
"id": 3,
"month": "2017-05-01"
}
{
"id": 4,
"month": "2017-06-01"
}
{
"id": 5,
"month": "2017-07-01"
}
{
"id": 6,
"month": "2017-08-01"
}
{
"id": 7,
"month": "2017-09-01"
}
{
"id": 8,
"month": "2017-10-01"
}
{
"id": 9,
"month": "2017-11-01"
}]
The problem with this is the DatePipe. It only has a transform function rather than formatDate.
Also it doesn't like years: [] = []

ngOnInit() {
this.years = this.volumeService.getVolumes().subscribe(volumes => {
this.volumes = volumes;
this.volumes.forEach(volume => {
if(!this.years || !(this.years.some(year => year.includes(volume.month.split('-')[0])))) {
this.years.push(volume.month.split('-')[0])
}
});
this.groupedVolumes = this.group(this.volumes);
this.dataOk = true;
}

Related

Angular 13 - How to get pager details from the JSON response

I work on Angular 13 and I face an issue in that I can't retrieve pager data from the JSON.
The items array returned success but I can't return pager details.
So how to do it?
{
"items": [
{
"id": 3,
"itemNameER": "قلم",
"itemNameEN": "pen",
"description": "1"
},
{
"id": 4,
"itemNameER": "قلم",
"itemNameEN": "pencil",
"description": null
},
{
"id": 5,
"itemNameER": "قلم",
"itemNameEN": "pen2",
"description": null
},
{
"id": 8,
"itemNameER": "car",
"itemNameEN": "car",
"description": "1"
},
{
"id": 9,
"itemNameER": "mobile",
"itemNameEN": "mobile",
"description": "1"
}
],
"pager": {
"numberOfPages": 2,
"currentPage": 1,
"totalRecords": 6
}
}
What I had try is:
items?:ItemsData[];
export interface ItemsData {
id:number;
itemNameER:string;
itemNameEN:string;
description:string;
}
retrieveAllItems(pageNumber: number = 0): void {
this.erpservice.getAll(pageNumber)
.subscribe(
data => {
this.items=data.items;
console.log(data);
},
error => {
console.log(error);
});
}
How to extract pager data from JSON for the numberOfPages, currentPage and totalRecords?
Updated post
This is the information for the getAll return type.
So how to get pager data details?
export interface DataWrapper {
items: ItemsData[];
}
getAll(pageNumber: number): Observable<DataWrapper> {
let params = new HttpParams();
if (pageNumber)
params = params.append('pageNumber', pageNumber);
let httpOptions = {
params: params
};
return this.http.get<DataWrapper>(baseUrl,httpOptions);
}
What I had try is:
pager: any;
this.pager = data.pager;
But I get an error:
Property 'pager' does not exist on type 'DataWrapper'.ts(2339)
<ul>
<li *ngFor="let item of items | paginate: { currentPage:pager.currentPage }; let i = index">
{{ pager.numberOfPages * (pager.currentPage - 1) + i }}
</li>
</ul>
The error message is quite clear. The DataWrapper interface doesn't have a pager property.
You need to:
Add the pager property into DataWrapper interface.
Define the IPager interface.
export interface DataWrapper {
items: ItemsData[];
pager: IPager;
}
export interface IPager {
numberOfPages: number;
currentPage: number;
totalRecords: number;
}

Read Nested JSON object in typescript in NestJs

I am new to type script and Nested JSON Object structure. I am using NestJs . Here is my JSON request
{
"recipes": [
{
"recipe_id": 1,
"ingredients": [
{
"ingredient_id": 2,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 1,
"quantity": 2,
"unit": "g"
}
]
},
{
"ingredient_id": 3,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 2,
"quantity": 2,
"unit": "g"
}
]
}
]
},
{
"recipe_id": 2,
"ingredients": [
{
"ingredient_id": 4,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 4,
"quantity": 2,
"unit": "g"
}
]
},
{
"ingredient_id": 5,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 5,
"quantity": 2,
"unit": "g"
}
]
}
]
}
]
}
Below is my code to read above json request
public async createMealRecipe(request) {
try{
const ingredientData = request.recipes.flatMap(item => {
return item.ingredients.map(({ingredient_id, quantity, unit}) =>{
return {
recipe_id: item.recipe_id, ingredient_id, quantity, unit
}
})
});
const nutrientData = request.recipes.flatMap(item1 => {
return item1.nutrients.map(({nutrient_id, quantity, unit}) =>{
return {
recipe_id: item1.recipe_id, nutrient_id, quantity, unit
}
})
});
console.log(ingredientData);
console.log(nutrientData);
}catch(e) {
console.log('e', e);
throw e;
}
}
console.log(ingredientData); is working fine, but when i try to log this console.log(nutrientData); i am getting map undefined error . Please correct me. Actually I am new to nestjs / typescript.
EDIT: `So instead of map function is there any possibility to traverse using forEach loop ?`
The issue is that request.recipes.flatMap(item1 => { doesn't give you an object representing a nutrient. item1 in this case is a recipe such as
{
recipe_id: 1,
ingredients: [
{ ingredient_id: 2, quantity: 4, unit: 'g', nutrients: [Array] },
{ ingredient_id: 3, quantity: 4, unit: 'g', nutrients: [Array] }
]
}
which also makes sense because the loop is no different than the one in which you loop over recipes above. If you'd like to loop over the nutrients of each recipe, you need to loop over the item1.ingredients array first. An example of this would be something like the following:
const nutrientData = request.recipes.flatMap(recipe => {
return recipe.ingredients.map(({ ingredient_id, quantity, unit, nutrients }) => {
return nutrients.map(({ nutrient_id, quantity, unit }) => {
return {
recipe_id: recipe.recipe_id, nutrient_id, quantity, unit
};
});
});
});

Cannot use *ngFor for a two-dimensional array in Angular

I saw many similar questions but the solutions there didn't work for me. I want to display orders in Angular.
I receive clients' orders in Json format from Spring. Like this:
[
{
"id": 1,
"orderProducts": [],
"numberOfProducts": 0
},
{
"id": 2,
"orderProducts": [
{
"quantity": 4,
"product": {
"id": 1,
"brand": "apple",
"name": "iphone11",
"categoryId": 1
}
}
],
"numberOfProducts": 1
},
{
"id": 3,
"orderProducts": [
{
"quantity": 9,
"product": {
"id": 1,
"brand": "apple",
"name": "iphone11",
"categoryId": 1
}
},
{
"quantity": 6,
"product": {
"id": 2,
"brand": "xiaomi",
"name": "Note10",
"categoryId": 1
}
},
{
"quantity": 1,
"product": {
"id": 6,
"brand": "cccccccccccccccc",
"name": "cccccccccccccc",
"categoryId": 1
}
}
],
"numberOfProducts": 3
},
{
"id": 4,
"orderProducts": [
{
"quantity": 5,
"product": {
"id": 1,
"brand": "apple",
"name": "iphone11",
"categoryId": 1
}
}
],
"numberOfProducts": 1
}
]
So i created a class in Angular to accept it.
db-orders.ts
export class DbOrders {
id: number;
orders: ProductOrder[];
numberOfProducts: number;
constructor(orders: ProductOrder[]){
this.orders = orders;
}
}
product-order.ts
export class ProductOrder {
product: Product;
quantity: number;
constructor(product: Product, quantity: number){
this.product = product;
this.quantity = quantity;
}
}
product.ts
export class Product {
id: number;
brand: string;
name: string;
category: ProductCategory;
constructor(){}
}
Here is a service class.
order.service.ts
export class OrderService {
private orderUrl: string = 'http://localhost:8080/orders';
constructor(private http: HttpClient) { }
saveOrder(order: ProductOrders) {
console.log("Hello")
return this.http.post<ProductOrders>(this.orderUrl, order);
}
public findOrders(): Observable<DbOrders[]> {
return this.http.get<DbOrders[]>(this.orderUrl);
}
}
order-list.component.ts
export class OrderListComponent implements OnInit {
receivedOrders: DbOrders[] = [];
constructor(private orderService: OrderService) { }
ngOnInit(): void {
this.orderService.findOrders().subscribe(
data =>{
this.receivedOrders = data;
}
);
}
}
order-list.component.html
<div *ngFor="let receivedOrder of receivedOrders">
<p>Number of Products in the order: {{receivedOrder.numberOfProducts}}</p>
<div *ngFor="let order of receivedOrder.orders">
<h1>Product name: {{ order.product.name }}</h1>
</div>
</div>
In this case, only the number of products is displayed,nothing else:
I tried to add a toArray method:
<div *ngFor="let order of toArray(receivedOrder.orders)">
ngOnInit(): void {
this.orderService.findOrders().subscribe(
data =>{
this.receivedOrders = data;
}
);
}
toArray(orders: object) {
return Object.keys(orders).map(key => orders[key])
}
Doesn't work.
Also i tried to add indexes.
<div *ngFor="let receivedOrder of receivedOrders; let i=index"">
<p>Number of Products in the order: {{receivedOrder.numberOfProducts}}</p>
<div *ngFor="let order of receivedOrder.orders; let j=index"">
<h1>Product name: {{ order.product.name }}</h1>
</div>
</div>
Doesn't work either.
What is my mistake? Thank you!
You seem to have a few problems. Firstly, your data structure does not match your classes.
E.g. your ProductOrder object should have an array of OrderProduct objects as that is what your data has.
Your constructor for ProductOrder never gets called because you are no instantiating the object from the class.
In simple terms, change your html to this for it to work:
<div *ngFor="let receivedOrder of data; let i=index">
<p>Number of Products in the order: {{receivedOrder.numberOfProducts}}</p>
<div *ngFor=" let order of receivedOrder.orderProducts; let j=index">
<h1>Product name: {{ order.product.name }}</h1>
</div>
</div>
You can also find a demo on StackBlitz.

How can I format following json data in c3js?

How can i format following json in c3js?.
I want projectcount as y axis,date as x axis and each line for different user.
Please help me to find out this.
{"ProjectList":[{"date":"18-07-2017","projectcount":2,"user":"Salva"},
{"date":"10-07-2017","projectcount":1,"user":"Jaspreet Kaur"},
{"date":"07-07-2017","projectcount":1,"user":"Sukanya Ray"},
{"date":"29-06-2017","projectcount":1,"user":"Asmita Bhurke"},
{"date":"06-08-2017","projectcount":2,"user":"Salman AP Homes"},
{"date":"31-07-2017","projectcount":1,"user":"Alena Sandra"},
{"date":"27-07-2017","projectcount":1,"user":"Salva"},
{"date":"25-07-2017","projectcount":2,"user":"Salva"},
{"date":"21-07-2017","projectcount":1,"user":"Jaspreet Kaur"},
{"date":"21-07-2017","projectcount":2,"user":"Sandeep Ghanekar"}]}
I'll take these three data points to illustrate:
{"date":"31-07-2017","projectcount":1,"user":"Alena Sandra"},
{"date":"27-07-2017","projectcount":1,"user":"Salva"},
{"date":"25-07-2017","projectcount":2,"user":"Salva"},
For every line you want, you make an array starting with line name.
Then you set its data, filling gaps with nulls.
And you have to set timeseries array (starting with "x") from first to last date:
var chart = c3.generate({
data: {
x: 'x',
xFormat: '%d-%m-%Y', // parse format
"columns": [
[
"x",
"25-07-2017",
"26-07-2017",
"27-07-2017",
"28-07-2017",
"29-07-2017",
"30-07-2017",
"31-07-2017"
],
[
"Salva",
2,
null,
1,
null,
null,
null,
null
],
[
"Alena Sandra",
null,
null,
null,
null,
null,
null,
1
]
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%d-%m-%Y' // display format
}
}
},
line: {
connectNull: true
}
});
See in action.
We can format the JSON as per the graph needs.You can creates the graph as follows
var items = {
"ProjectList": [{ "date": "07-18-2017", "projectcount": 2, "user": "Salva" },
{ "date": "07-10-2017", "projectcount": 1, "user": "Jaspreet Kaur" },
{ "date": "07-07-2017", "projectcount": 1, "user": "Sukanya Ray" },
{ "date": "06-29-2017", "projectcount": 5, "user": "Asmita Bhurke" },
{ "date": "08-06-2017", "projectcount": 1, "user": "Salman AP Homes" },
{ "date": "07-31-2017", "projectcount": 3, "user": "Alena Sandra" },
{ "date": "07-27-2017", "projectcount": 4, "user": "Sandeep Ghanekar" },
{ "date": "07-25-2017", "projectcount": 2, "user": "Salva" },
{ "date": "07-21-2017", "projectcount": 6, "user": "Jaspreet Kaur" },
{ "date": "07-04-2017", "projectcount": 5, "user": "Sandeep Ghanekar" },
{ "date": "07-08-2017", "projectcount": 7, "user": "Salva" },
{ "date": "07-21-2017", "projectcount": 2, "user": "Jaspreet Kaur" },
{ "date": "07-21-2017", "projectcount": 2, "user": "Sandeep Ghanekar" }]
}
var persons=[];
var valueToPush = new Array();
var uniqueArray = items.ProjectList.reduce(function (a, d) {
if (a.indexOf(d.date) === -1) {
a.push(""+d.date+"");
}
return a;
}, ['x']);
uniqueArray.sort(function(a, b) {
dateA = new Date(a),
dateB = new Date(b);
return dateA - dateB;
});
var nameArray = items.ProjectList.reduce(function (a, d) {
if (a.indexOf(d.user) === -1) {
a.push(""+d.user+"");
}
return a;
}, []);
valueToPush[0]=uniqueArray;
var i=1;
nameArray.forEach(function(c){
persons=[];
persons.push(""+c+"")
items.ProjectList.forEach(function(b){
if(c===b.user){
persons.push(b.projectcount)
}
else{
persons.push(null)
}
});
valueToPush[i]=persons;
i++;
});
var chart = c3.generate({
data: {
x: 'x',
xFormat: '%d-%m-%Y',
"columns": valueToPush
},
axis: {
x: {
type: 'category',
tick: {
format: '%d-%m-%Y'
}
}
},
line: {
connectNull: true
}
});
Mention JavaScript support Date formats
Try this JSFiddle

parsing json data into objects with type script

My json data:
{
"status": "OK",
"data": {
"id": 3,
"initials": "mci",
"nom": "chabli",
"prenom": "mohammed Yassin",
"password": "m1ltRoJZRS",
"username": "yassine.chabli#edu.umi.ac.ma",
"photo": null,
"enabled": true,
"roles": [{
"id": 2,
"roleName": "DP",
"topSupression": false,
"lesGrilles": [{
"id": 2,
"affecte": true,
"privilege": {
"id": 1,
"actionName": "AjouterAVV"
}
},
{
"id": 3,
"affecte": true,
"privilege": {
"id": 2,
"actionName": "ModifierAVV"
}
}
]
},
{
"id": 3,
"roleName": "CP",
"topSupression": false,
"lesGrilles": [{
"id": 4,
"affecte": true,
"privilege": {
"id": 1,
"actionName": "AjouterAVV"
}
},
{
"id": 5,
"affecte": true,
"privilege": {
"id": 2,
"actionName": "ModifierAVV"
}
}
]
}
],
"departement": {
"id": 1,
"libelle": "Software",
"topSupression": false,
"area": {
"id": 1,
"libelle": "Maroc",
"topSupression": false
}
}
},
"error": null
}
I get this data successfully in my angular component like this:
import {AfterContentInit, Component, OnInit} from '#angular/core';
import {UserService} from '../services/user.service' ;
import {User} from '../classes/user' ;
import {Departement} from '../classes/departement';
import {Region} from '../classes/region';
import {Role} from '../classes/role';
import {Grille} from '../classes/grille';
import {Privilege} from '../classes/privilege';
#Component({
selector: 'rb-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: User = new User() ;
dept: Departement = new Departement();
area: Region = new Region();
roles: Role[] ;
grilles: Grille[];
privilege: Privilege
status: string ;
error: string;
constructor(public _us: UserService ) {
}
ngOnInit() {
this._us.getOneUser().subscribe(
data => (this.user = data.data, this.status = data.status, this.error = data.error , this.dept = this.user.departement,
this.area = this.dept.area , this.roles = this.user.roles),
error => alert(error),
() => console.log(this.roles)
);
}
}
In my HTML view I try to show some attribute like {{user.username }} it works.
But when I try to show like user.roles[0].id or something like that I have some error in the console:
the property id is undefined
While when I'm logging the user variable in the console, I can see that the property id of my roles array exist.