Angular [object Object] result instead of data - json

I've been trying to display the json result i'm getting from my backend. However I'm not able to display this json fully in my angular front-end. The json I'm getting also has . and - in it's naming. These are my classes currently and i can display the name and title but the data returns [object Object]
How can i return the data object and use this for instead in a form?
Unfortunately I don't have the possibility to format the json in the back-end
Models
export interface Data {
"Cloud-Features:CloudFeatures": CloudFeatures
}
export interface CloudFeatures {
"redis.hosts": string
"sentinel.active": boolean
"script.type": ScriptType[]
}
export interface ScriptType {
name: string
features: string[]
}
export interface Root {
name: string
title: string
data: Data
}
Component
export class CloudFeaturesComponent implements OnInit {
cloudfeatures!: any;
constructor(private cloudfeatureservice : CloudFeaturesService, private titleService: Title) {
this.titleService.setTitle("Cloud Features")
}
ngOnInit(): void {
this.loadCloudFeaturesConfig();
}
loadCloudFeaturesConfig() {
this.cloudfeatureservice.getCloudConfig().subscribe(cloudfeatures => {
this.cloudfeatures = cloudfeatures
})
}
}
Maybe it's also better to use Root instead of any here?
Service
export class CloudFeaturesService {
baseUrl = environment.ApiUrl;
constructor(private http : HttpClient) {
}
getCloudConfig(){
return this.http.get<any>(this.baseUrl + 'cloudfeatures');
}
}
HTML
<div class="row">
<div class="tile sm-12">
<div class="content">
<div class="box">
<h1></h1>
<p>{{ cloudfeatures | json }}</p>
</div>
<div>
{{ cloudfeatures.name }}
</div>
<div>
{{ cloudfeatures.title }}
</div>
<div>
{{ cloudfeatures.data }}
</div>
</div>
</div>
</div>
JSON
{
"name":"CloudFeatures",
"title":"CloudFeatures model",
"data":{
"Cloud-Features:CloudFeatures":{
"redis.hosts":"TestURL2",
"sentinel.active":true,
"script.type":[
{
"name":"test123",
"features":[
"Start",
"test123",
"qwerty"
]
}
]
}
}
}

I assume your problem is that {{cloudfeatures.data}} only renders [object Object]. This happens, because 'cloudfeatures.data' is no primitive type, but an JSON object. If you want to render the whole JSON object, you should use the json pipe.
If you want to access a specific property of this object, you can use either dot notation or bracket notation. Bracket notation is needed in your case, since you have special characters in your object keys. Example:
{{ cloudfeatures.data["Cloud-Features:CloudFeatures"] }}

use json pipe for data
example
<div>
{{ cloudfeatures.data | json }}
</div>

Related

Access an Array inside an Object with square brackets inside a ngFor

Basically, I've created a HTML that similar to the example :
<div *ngFor="let formElements of formTemplate">
<div *ngFor="let opt of staticEnumVals[formElements.testId]">
<!-- do smth here -->
</div>
</div>
Basically formTemplate is an Array with Objects, each Object has a property called "testId".
staticEnumVals is an Object thats build like that
{
"testId": [ {},{},{} ],
"testId2" [ {},{},{} ],
}
The keys "testId" and "testId2" are actual keys that match the Keys from formTemplate[i].testId.
Basically I want to iterate through an array out of my staticEnumVals and the array is selected dynamically based on the id from the first *ngFor
Basically im looking for an elegant way to achieve my second iteration, square brackets doesnt work.
I think my problem is clear enough, im sorry for the weird title.
Thanks in advance
After adding types to the staticEnumVals this worked for me.
#Component({
selector: 'test',
template: `
<div *ngFor="let formElements of formTemplate">
<div *ngFor="let opt of staticEnumVals[formElements.testId]">
{{opt.name}}
</div>
</div>
`
})
export class TestComponent {
private formTemplate: { testId: string }[] = [
{testId: '3'}, {testId: '2'}, {testId: '3'}
];
private staticEnumVals: { [id: string]: [any] } = {
'1': [{name: 'id1'}],
'2': [{name: 'id2'}],
'3': [{name: 'id3'}],
};
}

Trouble getting data out of API using Vue JS

I'm having trouble iterating over data from a json file in Vue JS. I've got everything set up and have access to the json. What am I missing here:
JSON
{
"test": "example",
"data": [
{
"name": "My Name",
"address": "My Address"
}
]
}
Vue JS html
{{ someData['name'] }}
<ul>
<li v-for="item in someData" v-bind:key="item.id">
{{ item }}
</li>
</ul>
and my script:
created() {
this.$http.get('http://localhost:3000/properties.json').then(response => {
// get body data
this.someData = response.body
}, response => {
// error callback
});
}
The result I'm getting is:
Result
As you can see, in my v-for simply specifying item grabs each of the items here, but I want to be able to do something like {{ item['name'] }} and {{ item['address'] }}
The main problem is in your JSON file. VueJS v-for is iterating over the keys in your JSON file, in this case {{ item }} will be getting name and address. That is the reason of your output.
To solve this...
Format your JSON file as
[{name: 'John', address: 'Jane'}]
Doing this your VueJS v-for will be iterating over JSON array and {{ item }} will get the value { name: 'John', address: 'Jane' } and now you can do {{ item.name }} {{ item.address }}
An example here
EDIT: Update your API request code
created() {
this.$http.get('http://localhost:3000/properties.json').then(response => {
// get body data
this.someData = [response.body]
}, response => {
// error callback
});
}
You can simply do the following:
<template v-for="(item, key) in someData">
<span v-if="key == 'address'">{{item}}</span>
</template>
The crucial point is that the v-for="item in someData" part in the component's view iterates over values of the someData object, namely "John" and "Jane".
Depending on what exactly is your goal, you should either reformat the JSON to be an array of objects (as suggested by #F.bernal), or change the logic of v-for directive.

How to Iterate JSON properties in TypeScript

My question is very simple, I have a following JSON Typescript Object and I like to Iterate trought the JSON properties
{"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
The code used is the following angular TypeScript component:
export class DetailsOnlineQuoteModalComponent implements OnInit {
#Input() title;
#Input() values:string;
properties:JSON;
constructor(public activeModal: NgbActiveModal) { }
ngOnInit() {
this.properties=JSON.parse(this.values);
console.log(this.properties);
}
}
What I really need is to go through the key-value attributes of the JSON and show them in my HTML.
Many Thanks!
If you are using angular 6.1 use keyvalue pipe
<div *ngFor="let title of data | keyvalue">
{{title.key}}
</div>
For Angular 5
<div *ngFor="let key of dataKeys">
{{key}} ------------- {{data[key]}}
</div>
get dataKeys() { return Object.keys(this.data); }
Example:https://stackblitz.com/edit/keyvalue-pipe-qtaqnm
As per your comment, I'm assuming you want to do an ngFor on the HTML to display each one of the key-value pairs
<div *ngFor="let key of Object.keys(properties)">
{{properties[key]}} --> this is the value
</div>
You can get all the keys using Object.Keys and assign to a variable as follows,
this.properties=JSON.parse(this.values);
let response = Object.keys(this.propertie);
now you can use ngFor over it,
<div *ngFor="let key of response ">
{{properties[key]}}
</div>
component.ts
let obj = {"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
this.keyOfObj = Object.keys(obj);
html
<div *ngFor="let key of keyOfObj ">
{{obj[key]}}
</div>
unfortunately seems to be NOT working (with keyvalue) with ANGULAR_9
see here for a comparison of full different way of doing: https://stackblitz.com/edit/angular9-iterate-on-object-attribute
otherwise the answer by defining a method to do the job is still working.

How to implement nested data form in angular2

Here is Json schema :
{
"_id" : ObjectId("59031d77fd5e1c0b3c005d15"),
"resume_data" : {
"work_experience" : [
{
"company" : "example",
"website" : "example.com",
"position" : "Internship",
"highlights" : "Learn To Create API In Laravel Framework. and also Learn Angular 2 for Front end Development.",
"project_experience" : [
{
"projectName" : "Fb Project",
"teamMember" : "5",
"technology" : "PHP,Laravel-5,Angular-2,MongoDb",
"projectPosition" : "Back-end Developer"
}
]
}
]
}
}
Here is image:
I have reference of this answer but i don't know about nested form data. can anyone explain how to implement it.
Here is your code, which sets the data you are receiving from backend, here I have stored it in a variable data.
Please notice, this is a shortened version of your form, but the basics are there, you only need to add the few missing properties in corresponding form arrays.
The build of the empty form looks is just a FormArray named work_experience matching your json structure:
this.myForm = this.fb.group({
work_experience: this.fb.array([])
})
We add the fields when you are receiving the data, call a function called setWorkExperience in the callback when receiving data:
setWorkExperience(){
// get the formarray
let control = <FormArray>this.myForm.controls.work_experience;
// iterate the array 'work_experience' from your JSON and push new formgroup with properties and the inner form array
this.data.work_experience.forEach(x => {
// add the rest of your properties also below
control.push(this.fb.group({company: x.company, project_experience: this.setFormArray(x)}))
})
}
setFormArray is called from the previous function, where we patch the data with from project_experience to the inner form array:
setFormArray(x) {
// create local array which is returned with all the values from the 'project_experience' from your JSON
let arr = new FormArray([])
x.project_experience.map(y => {
// add the rest of your properties below
arr.push(this.fb.group({projectName: y.projectName}))
})
return arr;
}
The template would then look like this:
<form [formGroup]="myForm">
<!-- Outmost array iterated -->
<div formArrayName="work_experience">
<div *ngFor="let a of myForm.get('work_experience').controls; let i=index">
<h3>COMPANY {{i+1}}: </h3>
<div formGroupName="{{i}}">
<label>Company Name: </label>
<input formControlName="company" /><span><button (click)="deleteCompany(i)">Delete Company</button></span><br><br>
<!-- inner formarray iterated -->
<div formArrayName="project_experience">
<div *ngFor="let b of myForm.controls.work_experience.controls[i].controls.project_experience.controls; let j=index">
<h4>PROJECT {{j+1}}</h4>
<div formGroupName="{{j}}">
<label>Project Name:</label>
<input formControlName="projectName" /><span><button (click)="deleteProject(a.controls.project_experience, j)">Delete Project</button></span>
</div>
</div>
<button (click)="addNewProject(a.controls.project_experience)">Add new Project</button>
</div>
</div>
</div>
</div>
</form>
In the template you can see the buttons for add and delete of projects and companies. Adding and deleting companies are straightforward, where initCompany() returns a formGroup:
deleteCompany(index) {
let control = <FormArray>this.myForm.controls.work_experience;
control.removeAt(index)
}
addNewCompany() {
let control = <FormArray>this.myForm.controls.work_experience;
control.push(this.initCompany())
}
In the add project we pass as parameter from the template the current formArray control, to which we just push a new FormGroup:
addNewProject(control) {
control.push(this.initProject())
}
In the delete function we pass the current formarray as well as the index of the project we want to delete:
deleteProject(control, index) {
control.removeAt(index)
}
That should cover pretty much everything.
Plunker
Please Check it Out This
Plunker Here
Json Store Like This
{
"name": "",
"work_experience": [
{
"name": "asdasd",
"project_experience": [
{
"Project_Name": "asdasdasd"
},
{
"Project_Name": "asdasdasd"
}
]
}
]
}

How to use custom pipes Angular2

I have the following JSON object: http://pastebin.com/1TguvZXc
Here is my Models Component HTML:
<button *ngFor="let category of categories" (click)="chooseCategory(this.category)" type="button" name="button" class="btn btn-default" id="{{category}}">
{{category}}
</button>
<div *ngFor="let model of models?.models">
<div *ngFor="let year of model['years']">
<div *ngFor="let style of year['styles'] | chooseCategory">
{{model.name}}, {{style.submodel.body }}
</div>
</div>
A (pipe?) method from my models.component:
chooseCategory(selectedCategory: string): void {
if((selectedCategory === '')) {
this.filterByPipe.transform(this.models,
['models.years.styles.submodel.body'], selectedCategory);
}
}
Additionally, I would like to use the FilterByPipe pipe from ngx-pipes to filter out by category in models.years.styles.submodel.body.
The code from my HTML roduces the following error:
Unhandled Promise rejection: Template parse errors:
The pipe 'chooseCategory' could not be found ("or="let model of models?.models">
<div *ngFor="let year of model['years']">
<div *ngFor="let s[ERROR ->]tyle of year['styles'] | chooseCategory">
{{model.name}}, {{style.submodel.body }}
I think that you not even read the documentation. Yu should create pipe in this way:
#Pipe({
name: 'somePipe'
})
export class SomePipe {
transform(value: any[]): any[] {
//some transform code...
}
}
and then can you call that in HTML file in this way:
<div *ngFor="let elem of elements | somePipe"></div>
Dont forget to declare your pipe in module.
#NgModule({
declarations: [ SomePipe ]
})
That's what you use is a method, not a pipe.
If you want to executing pipe depend on (f.e.) button click you should build Pipe with argument:
#Pipe({
name: 'somePipe'
})
export class SomePipe {
transform(value: any[], args: any[]): any[] {
let someFlag: boolean = false;
if(args && args[0]) someflag = true;
if(someflag) {
//some transform code...
}
}
}
to call this pipe in this way
<div *ngFor="let elem of elements | somePipe : yesOrNo"></div>
and then can you use in your component method to click button
yesOrNo: boolean = false;
onClickButton(event: any) {
event.preventDefault();
yesOrNo = !yesOrNo;
}
Since you're importing the pipe and calling it from a button in your component, you don't need to call the pipe directly in your component. Also, chooseCategory is just a method, not a pipe. Then, remove the pipe from the following line:
<div *ngFor="let style of year['styles'] | chooseCategory">