how can we print the field attributes data in angular - javascript

[
{
"model":"products.productstable",
"pk":1,
"fields":{
"company":"STANDARD",
"description":"CHAKKARS BIG ",
"type":"Chakkars",
"productcase":1,
"quantity":100,
"units":"PKT",
"rate":150.0,
"retension":3.0,
"newrate":154.5,
"myretension":30.0,
"finalrate":200.85,
"retailrate":401.7,
"remarks":"ABC"
}
},
{
"model":"products.productstable",
"pk":2,
"fields":{
"company":"STANDARD",
"description":"SMALL",
"type":"Sparkler",
"productcase":1,
"quantity":100,
"units":"PKY",
"rate":100.0,
"retension":3.0,
"newrate":103.0,
"myretension":25.0,
"finalrate":128.75,
"retailrate":257.5,
"remarks":"SCDC"
}
}
]

If you want to display in template, you can use *ngFor as
<div *ngFor="let item of name">
<h2>Company: {{item.fields?.company}}</h2>
<p>Description: {{item.fields?.description}}</p>
<p>Type: {{item.fields?.type}}</p>
<p>Rate: {{item.fields?.rate}}</p>
</div>
Demo https://stackblitz.com/edit/angular-ejf6dw

You can simply use the es6 map function to create an instance of your array and retrieve the data fields.
export class SomeComponent implements Oninit{
ngOnInit(){}
someData =
[{"model": "products.productstable", "pk": 1, "fields": {"company": "STANDARD", "description": "CHAKKARS BIG ", "type": "Chakkars", "productcase": 1, "quantity": 100, "units": "PKT", "rate": 150.0, "retension": 3.0, "newrate": 154.5, "myretension": 30.0, "finalrate": 200.85, "retailrate": 401.7, "remarks": "ABC"}}, {"model": "products.productstable", "pk": 2, "fields": {"company": "STANDARD", "description": "SMALL", "type": "Sparkler", "productcase": 1, "quantity": 100, "units": "PKY", "rate": 100.0, "retension": 3.0, "newrate": 103.0, "myretension": 25.0, "finalrate": 128.75, "retailrate": 257.5, "remarks": "SCDC"}}]
// create a function within your class like
showfields(){
const fields = this.someData.map((data) => console.log(data.fields));
return fields;
}
// Call the showfield() function to perform the task
}
Demo: https://stackblitz.com/edit/angular-tpxp1j

You can just make the api call, and map the result to get the pk and field attribute.
this.myService.getFromAPI().subscribe(response => {
if (response && response.length) {
this.formattedResponse = response.map(item => {
return {
pk: item.pk,
fields: item.fields
};
});
console.log('rs', this.formattedResponse);
}
});
Complete demo code: https://stackblitz.com/edit/angular-c9ppa9

Related

Filter data using a multiselect. When selecting 2 or 3 options result need to throw only registers where options together exist

thank you in advance for reading me. So I have been working in a filte. Right now my filter works, however doesn't do what I want. The current status is. When I select 2 options or more. I get all the values inside the data that contains either optionA oder optionB.
See my example data below:
{
"_uid": "1",
"body": [
{
"_uid": "2",
"name": "John",
"image": {
"id": 6807178,
"filename": "https://",
"copyright": "",
"fieldtype": "asset",
"is_external_url": false
},
"gewerk": "Project Owner",
"skill": ["vuejs", "react", "symfony"],
"component": "person",
},
{
"_uid": "3",
"name": "Jean",
"image": {
"id": 6807182,
"filename": "https://",
"copyright": "",
"fieldtype": "asset",
"is_external_url": false
},
"gewerk": "UI",
"skill": ["svelte"],
"component": "person",
},
{
"_uid": "4",
"name": "Martha",
"gewerk": "Frontend",
"skill": ["vuejs", "react"],
"component": "person",
},
{
"_uid": "5",
"name": "Tom",
"gewerk": "UI",
"skill": ["svelte", "angular", "vuejs"],
"component": "person",
}
],
}
With that being says when I filter using this example combi(screenshot). I get Martha, Tom and John as a result. When what I actually want is to have only Tom as a result. because only Tom have both criterias together inside his skills data.
This is my current computed function:
filterPersonSkill() {
return this.getComponentPerson.filter((e) =>
e.skill.map((skill) => this.multiValue.includes(skill)).includes(true)
);
}
At the beginning I used includes instead of map and that worked half. Because I was getting the result only if I selected in the same order(in the multiselect) as the array skills was appearing. Example below
filterPersonSkill() {
return this.getComponentPerson.filter((e) =>
e.skill.includes(...this.multiValue)
);
}
Thank in advance for the advice and reading me.
I think, it will be much simpler, if you add checkbox for the user to use "exact" filtering, i.e. results which include only selected tags.
With such a checkbox you can do something like this:
// your vue component
export default {
data() {
return {
exactMatch: true,
}
},
methods: {
filterPersonSkillExactMatch() {
const result = [];
for (const p of this.getComponentPerson) {
if (p.skill.length === this.multiValue.length
&& this.multiValue.every(val => p.skill.includes(val))) {
result.push(p)
}
}
return result
}
// somewhere in your code (either computed prop or method):
filteredPersons() {
if (exactMatch) {
return this.filterPersonSkillExactMatch()
}
return this.filterPerson()
}
}
}

Lodash - Remove one property for every element in array without specify index

I'm building a component that allows me to compare two objects. It accepts a list of fields to compare and a list of fields that need to be ignored in string format
Here is an example of the object that will be compared:
{
// (..... More elements above .....)
taskData: {
"uniqueId": "OrdenTrabajo48",
"id": 48,
"position": 1,
"name": "Dirección Obra Civil",
"description": "Dirección Obra Civil Afecta: Sorda, Roberto",
"startDate": "2021-10-16T11:00:00.000Z",
"endDate": "2022-06-01T11:00:00.000Z",
"duration": 227,
"progress": 73,
"hours": 0,
"realHours": 15,
"predecessor": null,
"child": [],
"resourceInfo": [
{
"uniqueId": "Persona_1MJ0VE9G0",
"id": "OrdenTrabajo48Persona_1MJ0VE9G0",
"name": "Sorda, Roberto",
"group": "Subgerencia de Planes y Proyectos - SUB_PLAN_PROY_SIT",
"unit": 4.1667,
"startDate": "2021-10-16T03:00:00.000+00:00",
"endDate": "2022-06-01T02:59:59.000+00:00",
"hours": 0,
"realHours": 15,
"avatar": "http://localhost:8091/images/llama.jpg"
}
],
"comments": null,
"etiquetas": [],
"baseLineStartDate": null,
"baseLineEndDate": null
}
// (..... More elements below .....)
}
(But to clarify, it could be any object. The component is abstract and can be used anywhere)
The component doesn't know the structure of the object to compare, just the object and the paths in string format
I want to remove in every element of the array resourceInfo, the properties avatar, icon, label and color regardless the length of the array, but I don't know if there is a syntax to do that.
Also I want to remove the property realHours
This is what I tried:
const ignoredFields = [
'taskData.resourceInfo[?].avatar', //<--- It's not working
'taskData.resourceInfo[].icon', //<--- Neither this
'taskData.resourceInfo.label', //<--- Or this
'taskData.resourceInfo[0].color', //<--- This hardcode is working, but I don't know the length in that scope
'taskData.realHours' // <-- No problems here
];
const currentComparableObject = _.omit(obj, ignoredFields);
const oldComparableObject = _.omit(prev, ignoredFields);
var fieldsToOmit=[];
var resourceInfoFields=['avatar','icon','label','color'];
var globalFields=['realHours'];
taskData.resourceInfo.forEach((item,index)=>{
resourceInfoFields.forEach((field)=>{
fieldsToOmit.push(`resourceInfo[${index}].${field}`)
})
})
console.log( _.omit(taskData, fieldsToOmit.concat(globalFields)))
You do not need lodash to delete fields from an array. I mean you can if you really want to but, it is trivial to loop through the array and delete the fields you want.
#Yasser CHENIK isn't wrong just doesn't do a good job of explaining the solution.
Below I have included a thorough example so you can test for yourself.
NOTE this solution mutates the original array but, it is not difficult to use this concept to make an immutable version.
const taskData = {
"uniqueId": "OrdenTrabajo48",
"id": 48,
"position": 1,
"name": "Dirección Obra Civil",
"description": "Dirección Obra Civil Afecta: Sorda, Roberto",
"startDate": "2021-10-16T11:00:00.000Z",
"endDate": "2022-06-01T11:00:00.000Z",
"duration": 227,
"progress": 73,
"hours": 0,
"realHours": 15,
"predecessor": null,
"child": [],
"resourceInfo": [
{
"uniqueId": "Persona_1MJ0VE9G0",
"id": "OrdenTrabajo48Persona_1MJ0VE9G0",
"name": "Sorda, Roberto",
"group": "Subgerencia de Planes y Proyectos - SUB_PLAN_PROY_SIT",
"unit": 4.1667,
"startDate": "2021-10-16T03:00:00.000+00:00",
"endDate": "2022-06-01T02:59:59.000+00:00",
"hours": 0,
"realHours": 15,
"avatar": "http://localhost:8091/images/llama.jpg"
},
{
"uniqueId": "Persona_1MJ0VE9G0",
"id": "OrdenTrabajo48Persona_1MJ0VE9G0",
"name": "Sorda, Roberto",
"group": "Subgerencia de Planes y Proyectos - SUB_PLAN_PROY_SIT",
"unit": 4.1667,
"startDate": "2021-10-16T03:00:00.000+00:00",
"endDate": "2022-06-01T02:59:59.000+00:00",
"hours": 0,
"realHours": 15,
"avatar": "http://localhost:8091/images/llama.jpg"
},
{
"uniqueId": "Persona_1MJ0VE9G0",
"id": "OrdenTrabajo48Persona_1MJ0VE9G0",
"name": "Sorda, Roberto",
"group": "Subgerencia de Planes y Proyectos - SUB_PLAN_PROY_SIT",
"unit": 4.1667,
"startDate": "2021-10-16T03:00:00.000+00:00",
"endDate": "2022-06-01T02:59:59.000+00:00",
"hours": 0,
"realHours": 15,
"avatar": "http://localhost:8091/images/llama.jpg"
},
],
"comments": null,
"etiquetas": [],
"baseLineStartDate": null,
"baseLineEndDate": null
}
const fieldsToOmit = [
'avatar',
'icon',
'label',
'color',
'realHours'
]
console.log(taskData.resourceInfo);
taskData.resourceInfo.forEach(info => {
fieldsToOmit.forEach(field => {
delete info[field];
})
});
console.log(taskData.resourceInfo);
You can remove properties in a functional manner (immutable) by using destructuring:
const {realHours, ...result} = {
...taskData,
resourceInfo: taskData.resourceInfo.map(
({avatar, icon, label, color, ...keep}) => keep
)
};
console.log(result);
Thanks for the answers to all.
To solve partially the problem, I created a function that does the following:
It filters the references that contains [?] (i.e: taskData.resourceInfo[?].avatar)
Then obtain the first part of the string (That is, the path to reach the array) and the second part (property name)
Using _.get from lodash it retrieves the length of the array and creates a new fieldReference with the index, so loadash can read it.
private sanitizeArrays(obj: any, fieldReferences: string[]): string[] {
const fieldsDup = [...fieldReferences];
// Get Elements that contains [?] in the property name
const arrays = fieldsDup.filter(ignoredField => ignoredField.match(/\[\?]/g));
// Remove elements that contain [?] from ignoredFieldsDuplicated
fieldsDup.forEach((ignoredField, index) => {
if (ignoredField.includes('[?]')) {
fieldsDup.splice(index, 1);
}
});
// Get the properties names without [?]
const arrayPropertyName = arrays.map(ignoredField => ignoredField.split('[')[0]);
const afterArrayPropertyName = arrays.map(ignoredField => ignoredField.split(']')[1]);
// For each array that I have...
arrayPropertyName.forEach((array, index) => {
const length = _.get(obj, array).length;
for (let i = 0; i < length; i++) {
fieldsDup.push(array + '[' + i + ']' + afterArrayPropertyName[index]);
}
});
return fieldsDup;
}
Example input (if the object contains only one element in resourceInfo):
'taskData.resourceInfo[?].avatar',
'taskData.resourceInfo[?].icon',
'taskData.resourceInfo[?].label',
'taskData.resourceInfo[?].color',
'taskData.resourceInfo[?].fontColor',
'taskData.realHours'
Example output:
taskData.resourceInfo[?].icon
taskData.resourceInfo[?].color
taskData.realHours
taskData.resourceInfo[0].avatar
taskData.resourceInfo[0].icon
taskData.resourceInfo[0].label
taskData.resourceInfo[0].color
taskData.resourceInfo[0].fontColor
(javascript includes() isn't playing nice deleting the [?])
Also it doesn't work for nested arrays...

How to loop through and display API data containing a JavaScript Object

Live CodeSandbox link.
I'm trying to access and pull in data from an API, specifically the price text value below:
"price": {
"currency": "CAD",
"text": "500"
},
JS code (everything else pulls in fine, just the <p>${product.price.text}</p> I'm having trouble with):
// Fetch Data
async function getData() {
const res = await fetch(url);
const data = await res.json();
let output = "";
// Loop through first 'groups' array
data.groups.map(function (group) {
// Loop through each 'equipments' array
group.equipments.map((product) => {
// Define below variable to match cat products only
const catProducts =
product["dealer-name"] === "CATERPILLAR FINANCIAL SERVICES CORPORATION";
// If the dealer name is everything but cat products (aka only battlefield products)..
if (!catProducts) {
// Loop through each 'photos' array
product.photos.map(() => {
// Then output the data
// If year is undefined, replace with empty string
output += `
<div class="card">
<img class="img-fluid" src=${product.photos[0].text} alt=${
product.model
} />
<div class="card--body">
<h3>${product.year ?? ""} ${product.manufacturer} ${
product.model ?? ""
}</h3>
<p>${product.city ?? "City Not Available"}, ${product.state}</p>
<p>${product.hours} hours</p>
<p>${product.price.text}</p> <--- Not working
<a href='https://used.ca/en/${product["group-code"]}/${
product["serial-number"]
}' class="btn btn-primary">View Details</a>
</div>
</div>
`;
});
}
});
});
// Add to slider
$(".used-slider").slick("slickAdd", output);
}
getData();
Currently throwing a console error: "app.js:26 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'text')"
API structure:
{
"version": "5",
"company-code": "N001",
"language-code": "en-CA",
"total-count": 148,
"created-date": "2021-09-22T18:12:03.2387128+00:00",
"template-identifier": "4da31196-7f4b-4529-b832-90d40ef4a024",
"group-type-code": "ProductFamilyCategory",
"groups": [
{
"group-code": "Backhoe Loaders - Chargeuses-pelleteuses",
"group-name": "Backhoe Loaders",
"group-display-name": "Backhoe Loaders",
"count": 7,
"equipments": [
{
"id": "4536522",
"dealer-name": "DEALER NAME",
"GroupName": "Compact Track Loader",
"product-family-code": "CTL",
"product-family": "COMPACT TRACK LOADER",
"product-family-display-name": "Compact Track Loader",
"manufacturer-code": "CAT",
"manufacturer": "MANUFACTURER",
"model": "RUBBER TRACKS FOR CTL 259D ",
"serial-number": "XXXXX",
"year": "2016",
"hours": 0,
"city": "Ville St-laurent, Montréal",
"state": "QC",
"certification": "None",
"availability": "Available",
"price": {
"currency": "CAD",
"text": "500"
},
"product-family-categories": {},
"photos": [
{
"text": "https://s7d2.scene7.com/is/image/CatUsedProduction/wtk?JHNyYz04ZjRjN2UyYzJkMzFmZWNjY2NiZDQ1MTc2NTA4MGY3MiYkdHh0PUJBVFRMRUZJRUxEJTIwRVFVSVBNRU5UJTIwUkVOVEFMUyUyMCUyOFFVJUMzJTg5QkVDJTI5JjUxMTY2"
}
]
}
]
}
]
}
Anyone know why I'm unable to access the price text value but can access all the others?
The error implies that some products don't have a price property. You need to check for this before trying to access the text property. You can display a default placeholder instead.
You can use optional chaining to simplify this.
<p>${product.price?.text || "unknown"}</p> <--- Not working

Modifying keys for an object that has arrays of object

There is an object where each key is an array of objects.
For example, in the following example data is an object having keys where each key is an array of object(s):
{
"status": 200,
"message": "Successful",
"data": {
"manual": [
{
"vendor_id": 1,
"price": 4590,
"discounts": {
"micro": 0,
"macro": 120
},
"vendor": "Vendor 1",
"customer_rating": "3.0/5",
"sla_compliance": 90,
"system_flag": "Green"
}
],
"nearest": [
{
"vendor_id": 1,
"price": 4590,
"discounts": {
"micro": 0,
"macro": 120
},
"vendor": "Vendor 1",
"customer_rating": "3.0/5",
"sla_compliance": 90,
"system_flag": "Green"
}
],
"auto": [
{
"vendor_id": 1,
"price": 4590,
"discounts": {
"micro": 0,
"macro": 120
},
"vendor": "Vendor 1",
"customer_rating": "3.0/5",
"sla_compliance": 90,
"system_flag": "Green"
}
],
"ticket_id": 72
}
}
I need to add/delete keys from the each object that is inside the array. For example, I need to add name key for each object inside the key manual. Likeways for other arrays of objects like nearest, auto. What would be the way to do this?
I tried to modify one key, and it changes the complete object. How could I avoid the reference thing here?
Do you mean something like this?
Say your data structure is called cars:
var cars = {
"status": 200,
"message": "Successful",
"data": {
"manual": [
{
...
Then you could add a property called name to the items under the property manual like
cars.data.manual = cars.data.manual.map(i => Object.assign({name: 'My ' + i.vendor}, i));
And similarly, to other items under different properties.
You can
console.log(cars);
afterwards to verify the result.

Angular or JavaScript to format/beautify JSON

I'm trying to figure out how to format this json in angular this is the result from extending all models from multiple forms.
{
"identifications": {},
"insurances": [
{
"insurances": [
{
"category": "",
"compName": "",
"planType": "",
"note": ""
}
]
}
],
"medical": {
"doctors": [
{
"doctors": [
{
"firstname": "James"
"note": "James Bond Note"
},
{
"firstname": "Robin",
"note": "Lorem Ipsum Dolor"
}
]
}
],
"records": {}
}
Here's I need to achieve to insert it into the API.
{
"parent_id": 17,
"insurances": [{
"insurance_type": "",
"notes": ""
}],
"medical": {
"doctors": {},
"blood": {},
},
"records": {}
}
If you're really looking at just pretty-printing stuff, investigate JSON.stringify:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
If you're trying to change the object from one data representation to another (I'll note that the second object is structurally different from the first, not just a matter of whitespace), then you just need to write some javascript that does stuff like new.doctors = old[0].medical[1].doctors (example, not actual code)
This question is pretty old, but nowadays you should use the json filter. For example:
var data = {a: 1, b: 2};
Then in the template:
{{ data|json:2 }}
Should output
{
a: 1,
b: 2
}

Categories

Resources