How can I pass json variable to array of objects - json

im currently working on this project and im facing this error when I try to pass a variable (this.arrayObj) into the composals array.
ngOnInit() {
this.apiService.getComposals().subscribe((res) => {
console.log(res.tpoCampos);
this.arrayObj = res.tpoCampos;
});
}
Im getting the Json content from a Web Service.
export class AppComponent {
title = 'Form';
arrayObj: any;
composals: Composal[] = [
this.arrayObj,
];
}
This is the content from the webservice
{
"m_iPatientID":2,
"tpoCampos":[
{
"m_cColor":"#000000",
"m_cType":"combo",
"m_cOptions":[
"Sim",
"N\u00e3o"
],
"m_cQuestion":"",
"m_cAnswer":"2",
"m_eIdComposant":4443
},
{
"m_cColor":"#000000",
"m_cType":"combo",
"m_cOptions":[
"Sim",
"N\u00e3o"
],
"m_cQuestion":"",
"m_cAnswer":"2",
"m_eIdComposant":4448
}
]
}
How can I pass the json to the composal object inside the variable this.arrayObj?

I think this.arrayObj is already an array of objects, so it could be written like this
composals: Composal[] = this.arrayObj;
export class AppComponent {
title = 'Form';
arrayObj: any;
composals: Composal[] = this.arrayObj;
}

Related

How to add array items to imported model(interface) in Angular

Below is my model and I want to create a request as shown below.
export interface IItemFlow
{
itemId : number;
itemName:string;
}
export class ISaveItemFlowRequest {
itemFlowRequest:IItemFlow[];
userId:number;
}
Imported model in component.ts
import { ISaveItemFlowRequest, IItemFlow} from "../item/model/Iitemflowfile"
Save button click adding items into model by using push() .
this._saveItemFlowRequest.itemFlowRequest.push({itemId:101;itemName:'ABC'});
Error: Cannot read property 'itemFlowRequest' of undefined
My request should generate as follows.
{
"itemFlowRequest": [
{
"itemId": 1,"itemName":"ABC"
},
{
"itemId": 2,"itemName":"xyz"
}
],
"userId": 22
}
You need to initialize the this._saveItemFlowRequest;
this._saveItemFlowRequest: ISaveItemFlowRequest = {itemFlowRequest : [], userId: null}
this._saveItemFlowRequest.itemFlowRequest.push({itemId:101;itemName:'ABC'});
Another aproach is create a class with a constructor that implements ISaveItemFlowRequest

Replace an Url from Json with a button that gives URL to another function

I’m trying to implement a function in my web application, that can discover URLs in a loaded Json via Regular Expressions using angular. Afterwards the URLs get replaced with buttons and when the button gets clicked the exact URL who got replaced gets handed in another function in another component which loads the given URL.
Until now I’m at the point that I can replace the URL of the loaded JSON with a button. I’m using a pipe for that named transform-url.pipe:
import {
Pipe,
PipeTransform,
Input,
Component
} from '#angular/core';
import {
DomSanitizer
} from "#angular/platform-browser";
#Pipe({
name: 'transformUrl',
pure: false
})
export class TransformUrlPipe implements PipeTransform {
constructor(protected sanitizer: DomSanitizer) {}
transform(value: any, ): any {
if (value.match === 0) {
return value;
}
return this.sanitizer.bypassSecurityTrustHtml(
value.replace(/"url:\/\/.*\/.*\/.*"/g, "<button type='button' >Run</button>")
);
}
}
Hmtl:
<h3>Unrecognized JSON data:</h3>
<pre [innerHTML] = "genericJson | transformUrl"></pre>
Sample of Json:
"documentVersion": "1.0",
"documentType": "Urls",
"name": {
"request": {
"version": "1.0",
"abc": [
{
"productUrl": "url://awrtwtgsfgshsfh/sfg/v1/document/jsfhljhl564356lhgljhsljh5895hj",
"attributes": [
{
"attributeSet": {
"attributes": {
"426824828246824828282468248": {
"value": "1"
},
"647474373748648248282824": {
"value": "true"
}
}
}
}
]
},
"productUrl": "url://adgagjfjfjfjhf/sfg/v1/document/adfah5ahfah5jahlkhaliohßjkjlaß73-3",
"attributes": [
{
"attributeSet": {
"attributes": {
"426824828246824828282468248": {
"value": "1"
},
"647474373748648248282824": {
"value": "true"
}
}
}
}
]
},
I found nothing on google on how to do this specific task. Is a pipe even the best solution for this? I tried to implement functions in the pipe but it didnt work.
Another thing that i cant figure out is how i can make every button unique so the application knows which excat URL it should take when the button is clicked? And how can I select the URL and give it in another function in another component?
First of all rather than using pipe, I have created solution in Component only.
Stringify JSON which needs to be get values from. genericJson
Remove first and last ", which is matched in regex.
Using *ngFor, create buttons and pass separate link to click function.
Demo (check console for button click)
EDIT: NEW DEMO.
import { Component } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
name = "Angular";
genericJson = { ... some json ... }
formatedOutput: (string | boolean)[] = [];
ngOnInit() {
// adding formatting to make regex search easier
const jsonFormattedString = JSON.stringify(this.genericJson, null, 4);
this.formatedOutput = jsonFormattedString.split('\n');
}
onClick(out: string) {
// do whatever operation on link
const link = out.match(/url:\/\/.*\/.*\/.*/)[0];
console.log(link);
}
urlFound(out: string): boolean {
const match = out.match(/"url:\/\/.*\/.*\/.*"/);
if (match !== undefined && match !== null && match.length > 0) {
return true;
}
return false;
}
}
Use matched links in HTML template,
<div>
<div *ngFor="let out of formatedOutput">
<ng-container *ngIf="urlFound(out); else simple_json"><pre>{{out}}<button (click)="onClick(out)">Link</button></pre></ng-container>
<ng-template #simple_json><pre>{{out}}</pre></ng-template>
</div>
</div>
I think, you should do it like this instead of using pipe:
.html
<button (click)="goTo(genericJson.url)">Run</button>
.ts
genericJson = {
url: "www.google.com"
};
goTo(url: string) {
if (url) {
if (!url.includes("https")) {
url = "https://" + url;
}
window.open(url, "_blank");
}
}

Is there any way to bind jsonpath dynamically in angular 6

I am creating a reusable component in which I can pass any dynamic json so he'll able to handle that
what I tried is
mycomponent.html:
<div *ngFor="let Node of items">
{{ Node[getPath()]}}<br>
</div>
mycomponent.ts:
#Input()
path:any;
#Input()
items:any;
getData(){
var String="";
var data=this.path.split('.');
for(var i=0;i<data.length;i++){
if(i==0){
String+="'"+data[i]+"']";
}else if(i+1==data.length){
String+="['"+data[i]+"'";
}
else{
String+="['"+data[i]+"']";
}
}
return String;
}
The output of getData() function is like
'related']['name'
because the reasone is
in mycomponent.html i am using
{{Node[getData()]}}
so basically im trying to do is
{{Node['related']['name']}}
MainComponent.html:
<my-component path="related.name" items={{items}}></my-component>
Input Array
[
{
"related": [
{
"name": "first"
}
]
},
{
"related": [
{
"name": "second"
}
]
}
]
my expected output is like
first
second
I want to create that component as resuable so i can use anywhere in my project so give any suggestion to do that :(
When you create a dynamic component to handle the input JSON.
You could do two ways
Create the component.
mycomponent.html:
mycomponent.ts
mycomponent
#Input()
items:any;
When you integrate the component as any child then you could do as
<mycomponent [items]="items"></mycomponent>
or when you want to invoke as popup
then
let ngModelRef : NgbModalRef = this.ngbModalService.open(mycomponent );
ngModelRef.componentInstance.items= items;
return ngModelRef;

Parsing JSON Data working only for template(HTML) but not for Component Class(Typescript)

I would like to parse a json file to use, and extract data.
I don't know why the data extracted from my code work only for my html, but is empty for my typescript code...
json file to parse :
[
{
"appleWatch": "generation_3",
"bracelets": ["model_1","model_2","model_3"]
},
{
"appleWatch": "generation_4",
"bracelets": ["model_1","model_4","model_5"]
}
]
Typescript of my component:
export class AppleKitComponent implements OnInit {
constructor(private httpService: HttpClient) {}
arrAppleWatch: AppleWatchModel[] = [];
selectedWatch: AppleWatchModel = null;
url = '../../assets/json/appleKit.json';
ngOnInit() {
this.arrAppleWatch = this.parseAppleWatchData();
console.log(this.arrAppleWatch.toString() + 'test');
}
parseAppleWatchData() {
this.httpService.get('../../assets/json/appleKit.json').subscribe(
data => {
this.arrAppleWatch = data as AppleWatchModel[]; // FILL THE ARRAY WITH DATA.
},
(err: HttpErrorResponse) => {
console.log(err.message);
}
);
return this.arrAppleWatch;
}
}
My appleWatch model :
export class AppleWatchModel {
constructor(
public watch: string,
public bracelets?: string[],
public bracelet?: string
) {
}
}
HTML:
{{arrAppleWatch |json }}
My log should output :
[ { "appleWatch": "generation_3", "bracelets": [ "model_1", "model_2", "model_3" ] }, { "appleWatch": "generation_4", "bracelets": [ "model_1", "model_4", "model_5" ] } ]
but it just prints an empty string.
My html work and show the array :
[ { "appleWatch": "generation_3", "bracelets": [ "model_1", "model_2", "model_3" ] }, { "appleWatch": "generation_4", "bracelets": [ "model_1", "model_4", "model_5" ] } ]
There are a few issues with your implementation.
The httpService.get call call would be an async call. So it won't give you the data instantly. But you're trying to access it instantly. Hence you're not getting it in the Component Class.
Give this a try:
import { Component } from '#angular/core';
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
export interface AppleWatchModel {
watch: string;
bracelets?: string[];
bracelet?: string;
};
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private httpService: HttpClient) {
}
arrAppleWatch: AppleWatchModel[] = [];
selectedWatch: AppleWatchModel = null;
ngOnInit() {
this.parseAppleWatchData()
.subscribe(res => {
this.arrAppleWatch = res;
console.log('test: ', this.arrAppleWatch);
});
}
parseAppleWatchData() {
return this.httpService.get<AppleWatchModel[]>('/assets/appleKit.json');
}
}
Here, we're returning an Observable<AppleWatchModel[]> from parseAppleWatchData. So we can subscribe to it in the ngOnInit to get the actual data.
Here's a Working Sample StackBlitz for your ref.
Your output is empty because you don't take the asynchronous nature of http requests into account. parseAppleWatchData is returned with the original arrAppleWatch value (which is []) before the http response is received. If you add some logs you will see B comes before A. You can also remove the return value.
export class AppleKitComponent implements OnInit {
constructor(private httpService: HttpClient) {
}
arrAppleWatch: AppleWatchModel [] = [];
selectedWatch: AppleWatchModel = null;
url = '../../assets/json/appleKit.json';
ngOnInit() {
this.parseAppleWatchData();
log('B', this.arrAppleWatch);
}
parseAppleWatchData() {
this.httpService.get('../../assets/json/appleKit.json').subscribe(
data => {
this.arrAppleWatch = data as AppleWatchModel []; // FILL THE ARRAY WITH DATA.
console.log('A', data);
},
(err: HttpErrorResponse) => {
console.log(err.message);
}
);
}

Combine JSON data with Arrays, TypeScript (Ionic 3)

I am trying to include some data as string in one of my access modifiers (public pieChartLabels) which is an array. I've been checking with console.log what I was getting from my provider, and it works fine, but I just can't make it work when I try with the modifiers.
I have understood that functions such as ionViewDidLoad() are executed until the modifiers are ready to be used, therefore I used my provider inside the array to get JSON data.
JSON:
{
"name": "progress",
"overall": [
"30",
"5",
"3",
"62"
]
}
HTML:
<ion-content padding class="ionContent" *ngFor="let p of allProducts">
<div style="display: block" class="pieChart">
<canvas baseChart height="50%" width="50%"
[data]="p.overall"
[labels]= "pieChartLabels"> <!--I want to include a number after the label-->
</canvas>
</div>
</ion-content>
TypeScript:
export class LoginPage {
public allProducts = [] as any;
public percentages = [] as any;
public newPercentages = [] as any;
constructor(public navCtrl: NavController, public navParams: NavParams, private screenOrientation: ScreenOrientation, private dataProvider: DataProvider) {
}
ionViewDidLoad() { // As soon as the page is loaded this executes
this.dataProvider.getProducts()
.subscribe((Response: Array<any>) => {
this.allProducts = [Response]; // Getting data as array for HTML
this.percentages = Response; // Getting data as object
console.log("First", this.allProducts);
console.log("Second", this.percentages.name);
});
}
ionViewDidEnter(){ // Executes after ionViewDidLoad()
console.log("I want this: ", JSON.stringify(`${this.percentages.overall[0]}`));
console.log("Final Test: ",JSON.stringify(`${this.dataProvider
.getProducts().subscribe((Response: Array<any>) => {
this.newPercentages = Response;}),this.newPercentages.name}`),this.newPercentages.overall)
}
public pieChartLabels:string[] = [ // <-----HERE IS MY PROBLEM!
'Propuestas Originales Cumplidas'+JSON.stringify(`${this.dataProvider
.getProducts().subscribe((Response: Array<any>) => {
this.finalPercentages = Response;}),this.finalPercentages.overall[0]}`)+'%',
}
What I get in the console.log is exactly what I expect:
[app-scripts] [01:46:16] console.log: First [object Object]
[app-scripts] [01:46:16] console.log: Second progress
[app-scripts] [01:46:16] console.log: I want this: "30"
[app-scripts] [01:46:16] console.log: Final Test: "progress"
30,5,3,62
But what I get in my simulator is "Undefined", as if the value of finalPercentages wasn't stored.
Simulator Screenshot
The output that I want is "Propuestas Originales Cumplidas 30%".
What can I do? Also, is there a way to combine it in HTML instead? Something like [labels]="source1,source2"?
Why don't you set your pieChartLabels in the subscribe callback of your provider?
Code might look something like this:
export class LoginPage {
public allProducts = [] as any;
public percentages = [] as any;
public newPercentages = [] as any;
public pieChartLabels = []; // If pieChartLabels should have a default value, set it here
ionViewDidLoad() {
this.dataProvider.getProducts()
.subscribe((Response: Array<any>) => {
this.allProducts = [Response];
this.percentages = Response;
// Set your pieChartLabels here
this.pieChartLabels = ['Propuestas Originales Cumplidas ' + this.percentages.overall[0] + '%'];
});
}
}