I am new to angular. I was trying to clone a set of elements which is working fine but I am not able to get the latest value of the new cloned element when I console it or in the view.
It might be because of a variable called temp which is getting the cloned values. How to get the respective fields values in the console like
example=[{
exp1="aaa",
exp2="bbb",
exp3="tea"
},{
exp1="ddd",
exp2="eee",
exp3="mango"
}]
?
Please refer the below link for the working copy of the code:
https://stackblitz.com/edit/angular-gvwv4g-h2sxnd
You can use it this way
this.example.push(JSON.parse(JSON.stringify(this.temp)));
Please refer the below example
https://stackblitz.com/edit/angular-gvwv4g-effowp
You need to copy your form filled values into a new object, then pushing this new object into your array, then you can reset your object value, so the new added line will be empty.
I have edited your input-overview-example.ts as follow
import { Component , OnInit} from '#angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '#angular/forms';
/**
* #title Basic Inputs
*/
#Component({
selector: 'input-overview-example',
styleUrls: ['input-overview-example.css'],
templateUrl: 'input-overview-example.html',
})
export class InputOverviewExample implements OnInit {
// test Start
foods=["mango","tea","apple"]
example= [ ];
temp: any;
//test ends
ngOnInit() {
this.initTemp();
this.example.push(this.temp);
}
testAdd(){
console.log(this.temp)
console.log(JSON.stringify(this.example)+"-------");
this.initTemp();
this.example.push({
exp1: this.temp.exp1,
exp2: this.temp.exp2,
exp3: this.temp.exp3,
});
}
initTemp() {
this.temp = {
exp1:"",
exp2:"",
exp3:""
}
}
}
Related
what I am trying here is to use the variables i read off the route to determine which blog to use from the json. the json file is an array of sections which further contain an array of blogs.
while the code runs perfectly if i put id1 and id2 as 1, 2 in the this.blog=data[this.id1].blogs[this.id2]; line,
I am getting an error TypeError:_data_json__WEBPACK_IMPORTED_MODULE_2___namespace[this.id1] is undefined on no change.
import { Component, OnInit } from '#angular/core';
import * as data from '../data.json';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-post',
templateUrl: './post.component.html',
styleUrls: ['./post.component.css']
})
export class PostComponent implements OnInit {
id1;
id2;
sub;
blog;
constructor(
private _Activatedroute: ActivatedRoute,
private _router: Router
) {}
ngOnInit() {
this.sub = this._Activatedroute.paramMap.subscribe(params => {
console.log(params);
this.id1 = Number(params.get('id1'));
this.id2 = Number(params.get('id2'));
this.blog = data[this.id1].blogs[this.id2];
});
}
}
also on replacing id1, id2 with any variable, i get the same error.
edit: I changed the import * as data from '../data.json'; to const data=require('../data.json'); and i got the correct result. however, i still dont understand why this happens and would like to keep the question open for same.
params.get method returns only string. You can try converting it into number before passing it to data.
Try using the line written below
this.blog = data[+this.id1].blogs[+this.id2];
My intention is to send data from one component to another. The user can choose between 3 different offers - the click events provide different data (in this case numbers from 1 to 3) - these data is saved in the Sender as "selectedDiv" - (following isn't working) data from "selectedDiv" shall be send to Reciever and is also to be updated when "selectedDiv" in the sending component changes.
I've already found suggestions on stackoverflow.com, but none of them worked out for me.
Summarized:
The component which is supposed to send data contains a number which is to be forwarded to a different component.
My progress so far:
Service:
export class SelectedService {
selectedDiv: number;
changeNumber(div: number) {
this.selectedDiv = div;
}
}
Sender:
import { Component, OnInit } from '#angular/core';
import {SelectedService} from '../selected.service';
#Component({
selector: 'app-wedding',
templateUrl: './wedding.component.html',
styleUrls: ['./wedding.component.css'],
providers: [SelectedService]
})
export class WeddingComponent implements OnInit {
selectedDiv: number;
public onChoose(event): void {
this.selectedDiv = event;
this.selectedService.changeNumber(this.selectedDiv);
}
constructor(private selectedService: SelectedService) {
}
ngOnInit() {
}
}
Reciever:
import { Component, OnInit } from '#angular/core';
import {SelectedService} from '../selected.service';
#Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css'],
providers: [SelectedService]
})
export class ContactComponent implements OnInit {
selectedDiv: number;
constructor(private selectedService: SelectedService) {
this.selectedDiv = this.selectedService.selectedDiv;
}
ngOnInit() {
}
}
Edit:
The first approach showed following error: this.selectedService.changeNumber is not a function
Screenshot from Augury (receiving component somehow remains empty):
Sending WeddingComponent:
WeddingComponent
Receiving ContactComponent:
ContactComponent
The issue is that you are providing the SelectedService directly in the components, therefore you are getting two different instances of the same class.
You have 3 solutions:
Register the provider in a component parent of both WeddingComponent and ContactComponent
Register the provider in the module containing both WeddingComponent and ContactComponent
Add provideIn: root as a parameter of the Injectable decorator directly in the service
Depending on the scope of the service you need to choose one option.
This should be the simplest thing. I have a component that calls a service that imports a local JSON directly (see Import JSON directly with Angular 7)
It reads the JSON contents fine, but the pages property is undefined. I think I set everything up based on the StackBlitz in that link, there doesn't seem to be much to it. There isn't any HTML yet, this is all just via the console. It's in app.component.html.
Reading local json files json.service.ts:14
[{…}]0: {name: "Home"}length: 1__proto__: Array(0) json.service.ts:15
undefined home.component.ts:31
json.service.ts:
import { Injectable } from '#angular/core';
import SampleJson from '../assets/SampleJson.json';
export interface JsonInterface {
name: any;
}
#Injectable()
export class JsonService {
ngOnInit() {
console.log('Reading local json files');
console.log(SampleJson);
}
}
home.component.ts:
import { JsonService, JsonInterface } from '../json.service';
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(service: JsonService) {
service.ngOnInit();
};
#Input() pages: JsonInterface;
ngOnInit() {
console.log(this.pages);
}
}
Sample.json
{ "name":"Home" }
If I understand your log correctly, it works as expected:
constructor(service: JsonService) {
service.ngOnInit();
};
You request the service and you get an instance. Then you call ngOnInit:
ngOnInit() {
console.log('Reading local json files');
console.log(SampleJson);
}
Now it logs the "reading…" and the content of your json file.
ngOnInit() {
console.log(this.pages);
}
Then you log this.pages which is empty. You never filled it. You never did anything with your service or the data loaded in your service.
I think what you want is something like this
export class JsonService {
getPages() { return SampleJson; }
}
and in your component:
constructor(private service: JsonService) {}
ngOnInit() {
this.pages = this.service.getPages();
console.log(this.pages);
}
The sample code is not tested but I think you've got the point.
The problem is with pages. You have inly declared 'pages' as 'JsonInterface' which is only the type of 'pages' but never initialized with any value so it is undefined.. you need to write a function in Service as the above answer by #Christoph .
I hope you understand why this error occured and If you are not inputting a value to 'pages' from html you don't need to declare it as '#Input'.
I'm currently using ngx-formly to dynamically create a bunch of Angular forms from JSON, which works really nicely. I have a peculiar use case where a custom button on a form, should open a modal dialog containing another form on click, which would also contain a form created using ngx-formly. The example I saw on the ngx-formly site use a custom button, and creates a custom component with .ts files, but I want to avoid that since I would have several forms doing this, and I don't want to create different components for this.
Is there a way to trigger a modal dialog from an ngx-formly form, to show the modal with ngx-formly form without having to create multiple components(.ts) files for them?
Common Bootstrap Model with dynamic data
Example with jQuery:
https://stackblitz.com/edit/ngx-bootstrap-fh92s3
modal.service.ts
import {Injectable} from '#angular/core';
import {ModalModel} from './modal.model';
import {Subject} from "rxjs/Subject";
declare let $: any;
#Injectable()
export class ModalService {
modalData = new Subject<ModalModel>();
modalDataEvent = this.modalData.asObservable();
open(modalData: ModalModel) {
this.modalData.next(modalData);
$('#myModal').modal('show');
}
}
modal.component.ts
import { Component } from '#angular/core';
import { ModalService } from './modal.service';
import {ModalModel} from './modal.model';
declare let $: any;
#Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: [ './modal.component.css' ]
})
export class ModalComponent {
modalData: ModalModel;
constructor(private modalService: ModalService) {
this.modalService.modalDataEvent.subscribe((data) => {
this.modalData = data;
})
}
}
calling this service from any component
import { Component } from '#angular/core';
import { ModalService } from '../modal/modal.service';
import { ModalModel } from '../modal/modal.model';
declare let $: any;
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: [ './home.component.css' ]
})
export class HomeComponent {
modelData = new ModalModel();
constructor(private modalService: ModalService) {
}
open() {
this.modelData.header = 'This is my dynamic HEADER from Home component';
this.modelData.body = 'This is my dynamic BODY from Home component';
this.modelData.footer = 'This is my dynamic footer from Home component';
this.modalService.open(this.modelData);
}
}
Example without jQuery i.e with ngx-bootstrap: https://stackblitz.com/edit/angular-ngx-bootstrap-modal
Here is my first component
requirement:display data in second component which is sent by first component.
current status: i set data into service get set method and get also the data data but unable to display same data which is set by first component template .
import { Component } from '#angular/core';
import { ConfigService } from './myservicedata';
import { Router } from '#angular/router';// add file for navigate from one page to another page
#Component({
selector: 'tab-one',
templateUrl: './tabone.component.html',
providers:[ConfigService]
})
export class taboneComponent {
constructor(public configservice:ConfigService,private router:Router) {}
formData(data:any){
this.configservice.set_service_data(data);
console.log("value of data which is set by me into service"+ data);
}
// for navigate from one url to another url
navigate(){
this.router.navigateByUrl('/tab_two');
}
}
Here is my second component
import { Component ,OnInit} from '#angular/core';
import { ConfigService } from './myservicedata';
import 'rxjs/Rx'; // add this file for use the map feature.
#Component({
selector: 'tab-two',
templateUrl: './tabtwo.component.html',
// providers:[ConfigService]
})
export class tabtwoComponent {
public getterSetter:any=[];
// public store_service_data:any=[];
constructor(private configservice:ConfigService) {}
ngOnInit(){
this.configservice.get_service_data()
}
showdata(){
console.log( this.configservice.get_service_data());
}
};
Here is my service
import {Injectable} from '#angular/core';
import {Http,Response} from "#angular/http";
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
#Injectable()
export class ConfigService {
private _url:string="../mockData.json";
public serviceData:any=[];
get_service_data():any{
return this.serviceData;
// this.serviceData.map(
// (response:Response) => response.json()
// );
};
set_service_data(value:any):void{
this.serviceData=value;
};
constructor(private http:Http) {}
// Uses http.get() to load a single JSON file
getFriendsData():any {
return this.http.get(this._url).map(
(response:Response) => response.json()
);
}
};
Remove the providers array in your TaboneComponent and make sure ConfigService is in the providers array in your app.module.ts
Explanation:
In order to retrieve the information from the service what you want is to make sure that both your components reference the same instance on your ConfigService
Angular uses hierarchical dependency injection, which means whenever a dependency like your ConfigService is requested, Angular will traverse up the component tree to find a place where it has already been provided and pass that instance to the requester.
Because of this, you can easily create a singleton instance by providing a service in your app module as every component is a child of this.
When you provide the service like you have done in your TaboneComponent you are saying give me a new instance of this service even if one has already been provided somewhere else. Any component that is a child of tab-one will be able to get the data you have set in that service, but anything that is not a child will not.
You can read more about Angular's dependency injection here:
https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html