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']
};
Related
I am trying to show a list of Animals in my html page with their corresponding name and color.
My frontend gets the data from a spring backend that returns a list of Animals.
And I stumbled upon 2 questions that I have:
1)
I made the name and color properties private in the Animal class.
Code of the animal class:
interface AnimalJson {
name: string;
color: string;
}
export class Animal {
constructor(private name: string, private color: string) {}
static fromJSON(json: AnimalJson): Animal {
const a = new Animal(json.name, json.color);
return a;
}
}
code of my animal-component:
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs';
import { DataServiceService } from '../data-service.service';
import { Animal } from '../models/Animal';
#Component({
selector: 'app-animal',
templateUrl: './animal.component.html',
styleUrls: ['./animal.component.css'],
})
export class AnimalComponent implements OnInit {
public animals: Observable<Animal[]>;
constructor(private dataService: DataServiceService) {
this.animals = new Observable<Animal[]>();
}
ngOnInit(): void {
this.animals = this.dataService.getAnimals();
}
}
code of the service:
#Injectable({
providedIn: 'root',
})
export class DataServiceService {
constructor(private http: HttpClient) {}
getAnimals(): Observable<Animal[]> {
return this.http
.get<Animal[]>('http://localhost:8080/animals')
.pipe(map((animals: any[]): Animal[] => animals.map(Animal.fromJSON)));
}
}
code of the html-page:
<div *ngFor="let animal of animals | async">
<p>{{ animal.name }}</p>
</div>
Now when I try to get the animal.name, it gives an error that the name is private so I cant use it in my html page. How should I fix this? Should I just make it public? Or is there something I forget?
2)
Is this how you work with observables? Or am I using my observables in a wrong way?
Using the http get methode to get the observable and than call it in my animal-component and use async in my html-file to go over all the values in it?
If you use private then it should not be used in the html, am not sure why you are using a class for initializing the array. Just use a simple map statement.
If you are going to show it in the HTML then don't make the property private.
So the changes are.
interface Animal {
name: string;
color: string;
}
Service will be.
#Injectable({
providedIn: 'root',
})
export class DataServiceService {
constructor(private http: HttpClient) {}
getAnimals(): Observable<Animal[]> {
return this.http
.get<Animal[]>('http://localhost:8080/animals')
.pipe(map((animals: any[]): Animal[] => animals.map((item: Animal) => ({name: item.name, color: item.color}))));
}
}
Note: class can also be used as an interface, so when using animal you defined the properties as private, so you are unable to use in the HTML.
I have two .ts files (editor.ts and editor_settings.ts), Corresponding to editor.ts i have creater editor.html file. Now what i am trying to call function inside editor_settings.ts on button click in editor.html.
editor.ts
import { EditorSetting } from '../app/editorSetting.component';
export class PadComponent implements OnInit, OnDestroy { ---- }
constructor(
private component: EditorSetting
) { }
submit() {
let userCode = this.component.editor.getValue();
console.log('Inside pad.componet.ts');
console.log(userCode);
}
editor.html
<button id="submit" type="button" class="btn btn-sm btn-run" (click)="submit()" [disabled]="loading"
style="background: #FF473A">
<i class="fa fa-play" aria-hidden="true"></i>
<span *ngIf="loading">Running</span>
<span else> Run </span>
</button>
Now, on button click in editor.html, i want to call function which is inside editor_settings.ts.
editor_settings.ts
export class EditorComponent implements OnInit, OnDestroy, OnChanges {--}
I am facing the following error:
inline template:0:0 caused by: No provider for EditorComponent!
To communicate two components that are not related to each other, you can use a service.
#Injectable({
providedIn: 'root',
})
export class YourService {
private yourVariable: Subject<any> = new Subject<any>();
public listenYourVariable() {
return this.yourVariable.asObservable();
}
public yourVariableObserver(value ?: type) {
this.yourVariable.next(value);
}
You import in yours components where you want use it this service.
import{ YourService } from ...
In Edit component :
submit(){
this.yourService.yourVariableObserver();
}
while in Editor_setting.ts
ngOnInit() {
this.sub=this.yourService.listenYourVariable().subscribe(
variable => {
this.callyourFunction();
}
)
}
Don't forget to unsubscribe to prevent memory leak
ngOnDestroy() {
this.sub.unsubscribe()
}
Another aproach valid if your editor is inside the editorSetting
<editor-setting>
<editor></editor>
</editor-setting>
Use Host in constructor
constructor(#Optional #Host() private component: EditorSetting) { }
I am trying to send parameters from my angular app using httpRequest.
I am getting back Null to my backend server.
I have checked with Postman and Fiddler both work with a json Object.
I have tried changing from Post to Get.
I am using Java RestAPI for the backend with apache Tomcat as the server.
This is my Service for login:
#Injectable({
providedIn: 'root'
})
export class LoginService {
private loginURL='http://localhost:8080/CouponSystemWeb/rest/loginpage/login'
constructor(private http:HttpClient) { }
public login(loginDetailes:LoginDetailes):Observable<LoginDetailes>{
return this.http.post<LoginDetailes>(this.loginURL,loginDetailes,{withCredentials:true})
}
}
This is my Login Component:
import { Component, OnInit } from '#angular/core';
import { LoginDetailes } from 'src/app/Entities/LoginDetailes';
import { LoginService } from 'src/app/services/login.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
public loggedin:boolean;
public loggedClient:string;
public errormessage:string;
public loginDetailes = new LoginDetailes();
constructor(private loginservice:LoginService,private router:Router) { }
ngOnInit() {
this.loggedin=false;
}
public onLogin():void{
const observable=this.loginservice.login(this.loginDetailes);
observable.subscribe((returnedLoginDetailes:LoginDetailes)=>{
alert("Login Aquired");
this.loggedin=true;
if(this.loginDetailes.clientType=="ADMIN"){
this.router.navigate(['/crtComp']);
}
else if(this.loginDetailes.clientType=="COMPANY"){
this.router.navigate(['/login']);
}
else if(this.loginDetailes.clientType=="CUSTOMER"){
this.router.navigate(['/login']);
}else{
alert("Wrong Login Detailes");
}
}, err => {
this.errormessage=err.console.error("Wrong Detailes please Check Again!");
alert(this.errormessage);
}
)}}
This is the login Entity :
export class LoginDetailes{
public name:string
public password:string
public clientType:string
constructor(){
}
}
I have tried ngModel but that didn't fix the problem.
I have tried changing my backend from Post to Get.
The problem happends only in the angular App. I can send parameters with fiddler and Postman without problem.
Ok the answer was not in the component or the service.
the problem was in the HTML i was missing the ngModel two way data binding so my App was sending null's.
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
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.