I try to create reusable component for input form. The page will call this tag and get data to form group.
CALL PAGE:
I want to call tag and get value into "test" which I create in FormGroup
<div class="row">
<proj-form-row-input [lable]="'Input 1'" [required]="true" formControlName="test"></proj-form-row-input>
</div>
HTML: I create form in this component
<div class="col-sm-6 col-xs-12">
<form [formGroup]="setupForm" class="form-horizontal">
<div class="form-group">
<label class="col-sm-5">
{{lable}}
<span *ngIf="required" class="required">*</span>
</label>
<div class="col-sm-7">
<input type="text" class="form-control" formControlName="data" />
</div>
</div>
</form>
</div>
TS: for sent data back
import { Component, OnInit, Input, forwardRef, Output, EventEmitter } from '#angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormGroup, FormBuilder } from '#angular/forms';
import { ValidateHelper } from '../../helper/validate-helper';
#Component({
selector: 'proj-form-row-input',
templateUrl: './form-row-input.component.html',
styleUrls: ['./form-row-input.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FormRowInputComponent),
multi: true
}
]
})
export class FormRowInputComponent implements OnInit, ControlValueAccessor {
#Input() public lable: string;
#Input() public required: boolean = false;
#Output() public data = new EventEmitter();
public setupForm: FormGroup;
public inputData: string;
constructor(
private fb: FormBuilder,
) { }
ngOnInit() {
this.initsetupForm();
}
writeValue(obj: string): void {
if (ValidateHelper.isNotEqualString(obj, this.inputData)) {
this.setInputData();
} else {
this.data.emit(obj);
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
}
private initsetupForm(): void {
this.setupForm = this.fb.group({
data: [''],
});
this.setupForm.controls['data'].valueChanges.subscribe((val) => {
this.writeValue(val);
});
}
private setInputData() {
this.inputData = this.setupForm.controls['data'].value;
this.data.emit(this.inputData);
}
private onChange(_: any) { }
private onTouched() { }
}
FormControlName "test" still got no value, how an I out the value that emitted back into "test"
Currently, I do not see that you are subscribing to the data: EventEmitter anywhere?
If you declare an EventEmitter to transfer data between two components, the other component will need to subscribe() to the event to receive the data.
In your other components contructor, if you have an instance of your FormRowInputComponent component, you subscribe as follow:
formRowInputInstance.data.subscribe(response => { this.someProperty = response });
Here is four different approaches of passing values between components
Related
I want to change an HTML view via *ngIf, based on a local variable, which should change based on a variable delivered through an observable from a shared service.
HTML
<div class="login-container" *ngIf="!isAuthenticated">
TypeScript of same component:
export class LoginComponent implements OnInit {
authenticationsSubscription;
isAuthenticated: boolean;
constructor(
private authService: AuthServiceService,
private router: Router,
private route: ActivatedRoute){}
getAuth(): Observable<boolean>{
return this.authService.validation();
}
ngOnInit() {
this.authenticationsSubscription = this.authService.validation().subscribe(auth => this.isAuthenticated = auth);
}
}
TypeScript of shared service AuthService:
export class AuthServiceService {
isAuthenticated: boolean;
validation(): Observable<boolean>{
return of(this.isAuthenticated);
}
}
While debugging I found out, the variable isAuthenticated in the LoginComponent does not change, on changes of the variable isAuthenticated of the AuthService. I also tried using pipe() and tap(), which did not change anything.
What am I doing wrong?
Convert your AuthServiceService to have the authentication state as a BehaviorSubject and return it as Observable as described below.
import { Observable, BehaviorSubject } from "rxjs";
export class AuthServiceService {
private isAuthenticatedSub: BehaviorSubject<boolean> = new BehaviorSubject(false);
set isAuthenticated(isAuthenticated: boolean) {
this.isAuthenticatedSub.next(isAuthenticated);
}
get isAuthenticated(): boolean {
return this.isAuthenticatedSub.value;
}
validation(): Observable<boolean> {
return this.isAuthenticatedSub.asObservable();
}
}
The actual subscription of your observable will only happens once, when the OnInit lifecycle hook is triggered when the component is initialized.
You can subscribe to a BehaviorSubject in order to catch value changes.
Stackblitz example
AuthService
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class AuthService {
isAuthenticated: BehaviorSubject<boolean>;
constructor() {
this.isAuthenticated = new BehaviorSubject<boolean>(false);
}
}
Component
import { Component, OnInit } from '#angular/core';
import { AuthService } from './auth.service';
import { Observable } from 'rxjs';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
isAuthenticated: Observable<boolean>;
constructor(private authService: AuthService) {}
ngOnInit() {
this.isAuthenticated = this.authService.isAuthenticated;
}
login() {
this.authService.isAuthenticated.next(true);
}
logout() {
this.authService.isAuthenticated.next(false);
}
}
Template
<div *ngIf="isAuthenticated | async; else notAuthenticated">
User is authenticated
</div>
<ng-template #notAuthenticated>
<div>User isn't authenticated</div>
</ng-template>
<button (click)="login()">Login</button>
<button (click)="logout()">Logout</button>
I created a small CRUD application using Angular and Laravel 5.5. In the application, I have three radio buttons and when I try to get the values of them, I get the error...
Type error saying it cannot read the type of data
Below are the relevant parts of my scripts...
HTML
<div class="form-group row">
<label f class="col-sm-5 col-form-label col-form-label-sm">Can you get over unsound mind?
<span class="req">*</span>
</label>
<label class="col-sm-1 col-form-label col-form-label-sm">
<input type="radio" name="unsound" [(ngModel)]="userDetails.isUnsoundMind" [value]="false"/>
<span> No</span>
</label>
<label class="col-sm-1 col-form-label col-form-label-sm">
<input type="radio" name="unsound" [(ngModel)]="userDetails.isUnsoundMind" [value]="true"/>
<span> Yes</span>
</label>
</div>
TypeScript
constructor(public data: DataService,private userService: UserService, private sanitizer: DomSanitizer, private route: ActivatedRoute, private router: Router, private iNcoreService: IncorporationService, private spinner: NgxSpinnerService, private httpClient: HttpClient) {}
userDataSubmit() {
const data = {
....
isUnsoundMind: this.userDetails['isUnsoundMind'],
....
};
console.log(data);
this.userService.userDataSubmit(data)
.subscribe(
req => {
console.log("successful");
},
error => {
console.log(error);
}
);
Model
export interface IUserData {
...
isUnsoundMind: string;
...
}
Service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Router } from '#angular/router';
import { APIConnection } from './connections/APIConnection';
import { Observable } from 'rxjs';
import { IUserData } from '../models/user.model';
#Injectable({
providedIn: 'root'
})
export class UserService {
url: APIConnection = new APIConnection();
constructor(private router: Router, private http: HttpClient) { }
userDataSubmit(data: IUserData): Observable<IUserData> {
return this.http.post<IUserData>(this.url.getUserDataSubmit(), data);
}
}
Controller
<?php
namespace App\Http\Controllers\API\v1\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Address;
use App\User;
use Storage;
use App;
use URL;
use App\Http\Helper\_helper;
class useritorController extends Controller
{
use _helper;
public function saveuserData(Request $request)
{
$userAddress = new Address();
$userAddress->address1 = $request->input('localAddress1');
$userinfo = new user();
$userinfo->is_unsound_mind = $request->input('isUnsoundMind');
$userinfo->save();
}
}
As far as I'm concerned, there's no such error in all the above scripts, but every time I try to add the data to the DB it gives the above error, Some say when we add the radio button there's a small chunk of code to be written in the TS script, but no forum gives a proper explanation about it. Can someone help me out on this or give me proper guidance on how to add a radio button data to the DB table using Angular 6 + Laravel 5.5?
in typescript code you have defined data. try to define data as follows and see if its work:
const data:IUserData = {
isUnsoundMind: this.userDetails['isUnsoundMind']
};
I have an issue where i'm displaying a webview on one view and then once the user logs in i'm navigating to another view but the html for that view won't display, only the action bar. Help appreciated!
This is the login component navigating to secure--
this.router.navigate(["/secure"], { queryParams: { accessToken: accessToken } }).then((success)=>{
console.log(success);
});
}
This is the secure component-
#Component({
moduleId: module.id,
selector: "ns-secure",
templateUrl: "secure.component.html",
})
export class SecureComponent implements AfterViewInit{
public accessToken: string;
public onceLoggedInSrc: string; //TODO
public htmlString: string;
public constructor(private _router:Router, private _activatedRoute: ActivatedRoute, private cdRef:ChangeDetectorRef) {
this.htmlString = '<span><h1>HtmlView demo in <font color="blue">NativeScript</font> App</h1></span>';
this._activatedRoute.queryParams.subscribe(params => {
this.accessToken = params["accessToken"];
console.log('accessToken2');
console.log(this.accessToken);
this.ngAfterViewInit();
});
}
ngAfterViewInit() {
console.log('accessToken');
}
I'm newbie angular2. I'm making a website to start playing this platform. The problem is that when I query the API news can not transform objects correctly. Although I think there is a problem with the promises.
The code component is as follows:
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { AuthenticationService } from '../Service/Authentication.service';
import { NoticiesService } from '../Service/Noticies.service';
import { Logger } from '../Service/Logger.service';
import { Noticia } from '../Model/Noticia';
#Component({
selector: 'my-home',
templateUrl: 'app/View/html/Home.component.html',
styleUrls: ['app/Content/css/app.component.css'],
})
export class HomeComponent {
llistaNoticies: Noticia[];
missNoticies = 'Noticies Actuals:';
authenticatedUser = localStorage.getItem('usuari');
sessionUp = this._serviceAuthentication.isSession;
constructor(
private _logger: Logger,
private _serviceAuthentication: AuthenticationService,
private _noticiesService: NoticiesService) { }
getNoticies(): void {
this._noticiesService.getNoticies()
.then(noticies => this.llistaNoticies = noticies);
console.log('getNoticies() passat!')
}
ngOnInit(): void {
this.getNoticies()
console.log('ngOnInit() passat!')
}
logOut() {
this._serviceAuthentication.logOut();
}
}
The Code of Service is:
import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
import { Http, Response,
Headers, RequestOptions } from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Noticia } from '../Model/Noticia';
#Injectable()
export class NoticiesService {
private URLNoticies = 'http://localhost:50541/api/Noticies';
constructor(
private _router: Router,
private _http: Http) { }
getNoticies(): Promise<Noticia[]> {
return this._http.get(this.URLNoticies)
.toPromise()
.then(response => response.json().data as Noticia[])
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
The component of HTML code:
<div class="block-general m-t-1 subTitolPag">
<h2 class="titolPag">NotÃcies d'actualitat:</h2>
</div>
<div class="row p-a-1">
<div id="block-central" class="block-sub col-md-6 offset-md-2">
<div *ngFor="let noticia of llistaNoticies">
<hr />
<div class="card">
<img class="card-img-top imgNoticia" src="{{noticia.PathImatge}}" alt="Card image cap" style="max-width: 100%;">
<div class="card-block">
<h4 class="card-title titolNoticia">{{noticia.Titol}}</h4>
<p class="card-text">{{noticia.Cos}}</p>
<div class="clearfix">
<h5 class="pull-xs-right">Autor: <span class="label label-default pull-xs-right">{{noticia.Autor}}</span></h5>
</div>
<div>
<h6 class="pull-xs-right">Data de: {{noticia.Data}}</h6>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 block-sub m-x-1 p-a-1">
<p>Usuari registrat: <span class="text-uppercase">{{authenticatedUser}}</span></p>
<div class="clearfix m-t-1">
<button type="submit" class="btn btn-primary pull-xs-right" (click)="logOut()">Desconecta</button>
</div>
</div>
</div>
And the class:
export class Noticia {
public Id: number;
public Titol: string;
public Cos: string;
public Autor: string;
public PathImage: string;
public Data: Date;
}
If someone finds where is the error and tell me where I can find clear promises would be very grateful.
Thank you!!
I recommend to use Observables.
#Injectable()
export class NoticiesService {
private URLNoticies = 'http://localhost:50541/api/Noticies';
constructor(
private _router: Router,
private _http: Http) { }
getNoticies(): Observable<Noticia[]> {
return this._http.get(this.URLNoticies)
.map(response => response.json().data as Noticia[])
.catch(this.handleError);
}
private handleError(error: any): Observable<any> {
console.error('An error occurred', error);
return Observable.of(error.message || error);
}
}
And consume your service:
getNoticies(): void {
this._noticiesService.getNoticies()
.subscribe(
noticies => this.llistaNoticies = noticies,
err => console.log(err)
);
console.log('getNoticies() passat!')
}
Thanks to tutorial on Angular 2 page called "Tour of Heroes", I managed to create a simple Angular 2 application. Then using Enitity Framework I decided to create a database. And fill the list of heroes from it (not from the file). I created Web Api Controller and added simple get method.
Then in hero.service.ts I call this method in order to get list of heroes. When I lunch my app it shows the list of heroes but without any values (name and id are blank). When I debug my application in the browser I can see this.heroes object in heroes.component.ts contains right data. So what is going on? Why aren't name and id showing?
hero.service.ts:
import {Injectable} from 'angular2/core';
import {HEROES} from './mock-heroes';
import {Hero} from './hero';
import {Http, Response} from 'angular2/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class HeroService {
public values: any;
constructor(public _http: Http) { }
private _heroesUrl = 'http://localhost:61553/api/values'; // URL to web api
getHeroes() {
return this._http.get(this._heroesUrl)
.map(res => <Hero[]>res.json())
.catch(this.handleError);
}
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
heroes.component.ts:
import {Component, OnInit} from 'angular2/core';
import {Router} from 'angular2/router';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
#Component({
selector: 'my-heroes',
templateUrl: 'templates/heroes.component.html',
styleUrls: ['styles/heroes-component.css'],
directives: [HeroDetailComponent]
})
export class HeroesComponent implements OnInit {
constructor(private _heroservice: HeroService, private _router: Router) { }
errorMessage: string;
public heroes: Hero[];
selectedHero: Hero;
ngOnInit() {
this.getHeroes();
}
onSelect(hero: Hero)
{
this.selectedHero = hero;
}
getHeroes() {
this._heroservice.getHeroes()
.subscribe(
value => this.heroes = value,
error => this.errorMessage = <any>error);
}
gotoDetail() {
this._router.navigate(['HeroDetail', { id: this.selectedHero.Id }]);
}
}
heroes.component.html:
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)">
<span class="badge">{{hero.Id}}</span> {{hero.Name}}
</li>
</ul>
<div *ngIf="selectedHero">
<h2>
{{selectedHero.Name | uppercase}} is my hero
</h2>
<button (click)="gotoDetail()">View Details</button>
</div>
hero.ts:
export class Hero {
Id: number;
Name: string;
}
Web API Controller:
using Microsoft.AspNet.Mvc;
using System.Collections.Generic;
using TestApplicationDataAccess;
using TestApplicationDataAccess.Entities;
namespace WebApplication2.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly TestAppDbContext _dbContext;
public ValuesController(TestAppDbContext dbContext)
{
_dbContext = dbContext;
}
// GET: api/values
[HttpGet]
public IEnumerable<Hero> Get()
{
return _dbContext.Heroes;
}
}
}
Hero Entity:
namespace TestApplicationDataAccess.Entities
{
public class Hero
{
public int Id { get; set; }
public string Name { get; set; }
}
}
JSON retrieved from WEB API Controller:
[{"Id":1,"Name":"Superman"}]
getHeroes() {
this._heroservice.getHeroes()
.subscribe(res=>{
this.heroes=res;
console.log(this.heroes); // make sure you get data here.
},
(err)=>console.log(err),
()=>console.log("Done")
);
}
Try this :public heroes: Hero[] = [];
In my case the issue was related to the visual studio 2015 bug. There was nothing wrong with the code itself. Sometimes changes made in vs were not refreshed in the browser. Updating vs to the latest version helped.