Angular form sends empty data - javascript

I have problem with sending data to server from my form in angular, i can get user current data from database and show them but i am not able to send data back, instead it sends empty values.
Screenshots
playload of sending data to server
profile edit page with current data
Code
HTML
<form [formGroup]="userUpdate" (ngSubmit)="update()" *ngIf="user">
<ion-item class="ion-margin-top">
<ion-label position="floating">Name</ion-label>
<ion-input type="text" [value]="user.name" formControlName="name"></ion-input>
</ion-item>
//rest of the fields
<ion-button class="ion-margin-top" type="submit" expand="full" color="success" >Update</ion-button>
</form>
profile.page.ts
export class ProfilePage implements OnInit {
public userUpdate: FormGroup;
imageURI: any;
user = null;
constructor(
private authService: AuthService,
private navCtrl: NavController,
private menu: MenuController,
private modalController: ModalController,
private alertService: AlertService,
private alertCtrl: AlertController,
public formBuilder: FormBuilder,
private camera: Camera,
) {
this.userUpdate = this.formBuilder.group({
name: ['', [Validators.required]],
username: ['', [Validators.required]],
email: ['', [Validators.email, Validators.required]],
password: ['', Validators.required],
phone: ['', [Validators.required]],
avatar: ['', [Validators.required]],
});
}
ngOnInit() {
this.menu.enable(true);
}
ionViewWillEnter() {
this.authService.getToken().then(() => {
if (this.authService.isLoggedIn) {
this.navCtrl.navigateRoot('/profile');
}
});
this.authService.user().subscribe((user: any) => {
this.user = user.success;
console.log('user success', user.success);
});
}
update() {
const userUpdate = this.userUpdate.value;
this.authService.update(
userUpdate.name,
userUpdate.username,
userUpdate.email,
userUpdate.password,
userUpdate.phone,
userUpdate.avatar = this.imageURI
).subscribe(
data => {
this.alertService.presentToast(data);
},
error => {
this.alertService.presentToast(error);
}
);
}
}
profile.service.ts
update(
name: String,
username: String,
email: String,
password: String,
phone: String,
avatar: String
) {
const headers = new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
'Authorization': 'Bearer' + " " + this.token.success.token
});
return this.http.post(this.env.BASE_URL + '/updateUser',
{
name: name,
username: username,
email: email,
password: password,
phone: phone,
avatar: avatar
}, { headers: headers }
);
}
Any idea why it sends empty data and how to fix it?

Don't set user value using HTML value attribute, Angular reactive form source of control is class so setting value in html does not add the value to formControl instance. Instead you can use setValue or patchValue method if you want to set Value dynamically to input field.
this.authService.user().subscribe((user: any) => {
this.user = user.success;
this.userUpdate.patchValue({
name:user.name,
username: user.username ,//Assuming user object has username property
email: user.email,
password: user.password ,
phone: user.phone
});
console.log('user success', user.success);
});
For More Info
Example

Related

Comparing Data in Subscribe Angular & Observable RXJS

I am new to Angular & have written below code using in-memory-web-api for Login POC,
DB-service.service:
import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
createDb() {
let users = [
{id: 1, username: 'user1', password:'user1', name:'John'},
{id: 2, username: 'user2', password:'user2', name:'David'},
{id: 3, username: 'user3', password:'user3', name:'Brad'},
{id: 4, username: 'user4', password:'user4', name:'Jim'},
{id: 5, username: 'user5', password:'user5', name:'Saun'}
];
return {users};
}
}
user.service:
import { loginUser } from '../_model/user';
#Injectable()
export class UserService {
private headers = new Headers({ 'Content-Type': 'application/json' });
private userUrl = 'api/users'; // URL to web api
constructor(private http: Http) {
}
getLogin(username: string, password: string) {
const url = `${this.userUrl}`;
return this.http.get(url).map(res => res.json());
}
}
model/user.ts
export class loginUser {
constructor(
public id: number,
public username: string,
public password: string,
public name: string) { }
}
login.component.ts
login(form: FormGroup) {
if (this.loginForm.valid) {
this.userData.getLogin(form.value.loginUserTxt, form.value.loginPassTxt)
.subscribe(
data => {
console.log(data);
//comparing the data from the array in DB-service.service
},
error => {
console.log("Fail");
});
}
My issue is that how can I compare that data in subscribe of login.component.ts with the input value.
I have update the code below in subscribe
this.loggedUser = this.userData.getAuthenticate(data, form.value.loginUserTxt, form.value.loginPassTxt)
if (this.loggedUser == "Invalid") {
//error
} else {
//redirect
}
Thanks all

Ionic 3 - After data load ngModel undefined

I'm a bit of a beginner in angular 4... tried to search for this many times in the past few months, but got no result, even though it seems the most simple thing.
It's an ionic app. User logs in, the whole user object is saved to localStorage. Have tried several plugins, but went with simple:
window.localStorage.setItem('User', JSON.stringify(user));
user object structure:
export class User {
constructor(
public token?: string,
public user_email?: string,
public email?: string,
public first_name?: string,
public last_name?: string,
public user_roles?: {
ID?: number,
caps?: {
administrator?: boolean,
},
roles?: object,
},
public id?: number,
public device_feedback?: boolean,
public role?: string,
public username?: string,
public billing?: Address,
public shipping?: Address
) {}
}
export class Address {
first_name?: string;
last_name?: string;
company?: string;
address_1?: string;
address_2?: string;
city?: string;
state?: string;
postcode?: string;
country?: string;
email?: string;
phone?: number
}
settings.ts: (I have added ngOnInit and this.platform.ready(){} because thought data is not ready or something...)
export class Settings implements OnInit{
[other vars]
user: User;
constructor(public storage: Storage, private platform: Platform) { }
ngOnInit() {
// this.storage.ready().then(() => {
// this.storage.get("User").then((data) => {
this.platform.ready().then(() => {
let data = window.localStorage.getItem('User');
if (data) {
this.user = JSON.parse(data);
this.email = this.user.user_email;
console.log('user', this.user);
console.log('this.user.user_email', this.user.user_email);
}
});
}
Settings.html
<ion-content>
<ion-list padding>
<ion-list-header>
Title
</ion-list-header>
<ion-item>
<ion-label color="primary" fixed>Email</ion-label>
<ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
</ion-item>
The user_email is displayed in the console.log, referenced as this.user.user_email and same property gives an error in the HTML... how is this possible? Same in the browser or the device: http://prntscr.com/i8rfhg
I have also tried with user: any, but got the same result...
How? Why? What am I missing?
Here's the ionic info:
#ionic/cli-utils : 1.19.1
ionic (Ionic CLI) : 3.19.1
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
#ionic/app-scripts : 1.3.0
Cordova Platforms : none
Ionic Framework : ionic-angular 3.0.1
System:
Android SDK Tools : 25.2.5
Node : v6.11.0
npm : 5.6.0
Thanks a lot!
You are trying to access the property user_email of your user object while it's null / before it's initialized.
Try:
user: User = {}; // initial value
Or:
<ion-list padding *ngIf="user">
<ion-list-header>
Title
</ion-list-header>
<ion-item>
<ion-label color="primary" fixed>Email</ion-label>
<ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
</ion-item>
you don't have instance of User in this.user.
export class User {
public token: string;
public user_email: string;
public email: string;
public first_name: string;
public last_name: string;
public user_roles : Object = {
ID: null,
caps: {
administrator: false,
},
roles: {},
};
public id: number;
public device_feedback: boolean;
public role: string;
public username: string;
public billing: Address;
public shipping: Address;
public set(data:any){
if(!data){
return;
}
this.token = data.token;
this.user_email = data.user_email;
this.email = data.email;
this.first_name = data.first_name;
this.last_name = data.last_name;
this.id = data.id;
this.device_feedback = data.device_feedback;
this.role = data.role;
this.username = data.username;
this.billing = data.billing;
this.shipping = data.shipping;
this.user_roles = data.user_roles;
} }
and
export class Settings implements OnInit{ [other vars]
user: User = new User(); constructor(public storage: Storage, private platform: Platform) { }
ngOnInit() {
// this.storage.ready().then(() => {
// this.storage.get("User").then((data) => {
this.platform.ready().then(() => {
this.user.set(window.localStorage.getItem('User'));
});
}
In ngOnInit, the callback for this.platform.ready() is executed asynchronously. Before that, user is undefined and [(ngModel)]="user.user_email" causes an error.
You can prevent that error with the safe navigation operator. Since it works only for one-way data binding, you should split [(ngModel)] in its two parts, [ngModel] and (ngModelChange). In addition to that change, you can keep the input element disabled until user is initialized, to prevent entering data that will be lost anyway.
[ngModel]="user?.user_email" (ngModelChange)="setUserEmail($event)" [disabled]="!user"
with the component method:
setUserEmail(value: string): void {
if (this.user) {
this.user.user_email = value;
}
}
The code is illustrated in this stackblitz, where the user object is initialized after a few seconds.
I use export interface and class.
export interface UserCaps
administrator: boolean;
}
export interface UserRole {
ID: null;
caps: UserCaps;
roles: any;
}
export interface Address {
first_name?: string;
last_name?: string;
company?: string;
address_1?: string;
address_2?: string;
city?: string;
state?: string;
postcode?: string;
country?: string;
email?: string;
phone?: number
}
export interface User {public token: string;
user_email: string;
email: string;
first_name: string;
last_name: string;
user_roles : UserRole;
id: number;
device_feedback: boolean;
role: string;
username: string;
billing: Address;
shipping: Address;
}
export class User {}
And i init my user with new Class()
user = new User();

Angular - Re-Populate form inputs from service

I have a basic angular component that allows some one to edit the details of a user once they go to their profile and click on "edit".
Component:
export class EditUserComponent implements OnInit {
// Define our vars
user: Users[];
editUserForm: FormGroup;
message: {};
displayMessage = false;
userID: number;
errorMessage: any = '';
constructor(
private fb: FormBuilder,
private _userService: UserService,
private activatedRoute: ActivatedRoute
) {
}
ngOnInit(): void {
// Get the userID from the activated route
this.activatedRoute.params.subscribe((params: Params) => {
this.userID = params['id'];
});
// Call our service and pass the UserID
this._userService.getUser(this.userID)
.then(res => {
this.user = res;
this.createForm();
});
}
// Generate the form
createForm() {
this.editUserForm = this.fb.group({
QID: ['', Validators.required],
favoriteColor: [''],
favoriteNumber: [''],
favoriteActor: ['']
});
}
}
Service:
// Fetch a single user
getUser(userID: number) {
return this._http.post(this.baseUrl + '/fetchUser', { "userID": userID }, { "headers": this.headers })
.toPromise()
.then(res => res.json())
.catch(err => { this.handleError(err); });
}
Interface:
export interface Users {
RecordID?: number;
QID: string;
favoriteColor?: string;
favoriteNumber?: number;
favoriteActor?: string;
}
I am trying to pass the values to my formGroup but I am having trouble figuring out how to access the values.
I assumed I could do something like this where I could access the user model and select a property from it but that is throwing an undefined error.
Would I pass the values here in the form group or bind them to the elements directly somehow? I am receiving the data back from the service just fine, just not sure how to get each of the values back to their respective fields.
createForm() {
this.editUserForm = this.fb.group({
QID: [this.user.QID, Validators.required],
favoriteColor: [''],
favoriteNumber: [''],
favoriteActor: ['']
});
}
If I understand correctly ... this is what my code looks like:
onProductRetrieved(product: IProduct): void {
if (this.productForm) {
this.productForm.reset();
}
this.product = product;
// Update the data on the form
this.productForm.patchValue({
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
});
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}
I'm using patchValue for the values and setControl for the array.
OR
Since you are creating the form after retrieving the data, you could do something like this:
createForm() {
this.editUserForm = this.fb.group({
QID: [this.user.QID, Validators.required],
favoriteColor: [this.user.favoriteColor],
favoriteNumber: [this.user.favoriteNumber],
favoriteActor: [this.user.favoriteActor]
});
}
AND just to be complete ... each input element needs a formControlName property like this:
<input class="form-control"
id="productNameId"
type="text"
placeholder="Name (required)"
formControlName="productName" />
<span class="help-block" *ngIf="displayMessage.productName">
{{displayMessage.productName}}
</span>
</div>
You can find a complete working example here: https://github.com/DeborahK/Angular2-ReactiveForms
Bind a submit event to your form, then use this.editUserForm.value to access the data from the form.
In the component template:
<form [formGroup]="editUserForm" (submit)="saveIt()">
In the Component:
saveIt() {
if (this.editUserForm.dirty && this.editUserForm.valid) {
alert(`Number: ${this.editUserForm.value.favoriteNumber} Actor: ${this.editUserForm.value.favoriteActor}`);
}
}

display an object in a select tag not working in angular 2

Hello I am new to angular I am facing a problem while displaying country name in a drop downlist ,the drop down is not displaying any option while data is retrieved in the type script I think I am runing into a problem of mapping the ts with the html correctly
here is my ts code
export class SignupComponent{
registrationForm: FormGroup;
username: AbstractControl;
useremail: AbstractControl;
countryCode: String = "JOR" ;
viewCountryCode: String = "JOR";
languageCode: String;
CountryId:number; countries = CountryMapping.countryCode;
submitAttempt: boolean = false;
userResponse: UserResponse;
apiResponseData: any;
newCountries = [];
urlCopied = true;
countryList: any =[];
constructor(public builder: FormBuilder, public homeService: HomeService,
private router: Router,private _http: Http,
private loaderService: LoaderService, private helperService:
HelperService, private translate: TranslateService) {
this.languageCode = "EN"
this.CountryId=96;
this.homeService.getCountryByIp().subscribe(UserResponse => {
this.userResponse = UserResponse;
if (UserResponse.success) {
var cc = UserResponse.data.countryCode;
cc=cc.toLowerCase();
this.viewCountryCode = cc;
}
});
ngOnInit() {
this.signUpDone = false;
this.createSignupForm();
this.getCountryList();
this.getMerchantType();
}
createSignupForm() {
this.registrationForm = this.builder.group({
username: ['', Validators.compose([
Validators.required,
UserNameValidator.userNameRange,
UserNameValidator.OnlyAlphabets
])],
useremail: ['', Validators.compose([
Validators.required,
EmailValidator.mailFormat,
EmailValidator.domainCheckFormat,
EmailValidator.mailLength,
EmailValidator.specialCharacters
])],
countryCode:[this.viewCountryCode],
commercialWebSiteLink: ['', Validators.compose([
Validators.required,
UrlValidator.urlFormat,
])],
corporateWebSiteLink: ['', Validators.compose([
Validators.required,
UrlValidator.urlFormat,
])],
merchantType: ['PSP']
});
this.username = this.registrationForm.controls['username'];
this.useremail = this.registrationForm.controls['useremail'];
this.commercialWebSiteLink = this.registrationForm.controls['commercialWebSiteLink'];
this.corporateWebSiteLink = this.registrationForm.controls['corporateWebSiteLink'];
this.regestrationErrorMessage = " ";
}
getCountryList() {
this.homeService.getCountryList().subscribe(response => {
if (response.success) {
this.countryList = response.data;
console.log("retrieved the country list");
}
});
}
<div class="form-group ">
<label class="control-label" for="countryCode">Country</label>
<select class="form-control" id="countryCode" formControlName="countryCode">
<option *ngFor="let country of countryList" [ngValue]="country" [attr.value]="country.countryCode" [selected]="country.countryName == viewCountryCode">
{{country.countryName}}</option>
</select>
</div>
I would really appreciate any help i really need to get this to work by tomorrow,so please help me
THAT IS funny it seems in the back end (Spring)no country list a query that is wrong was retrieving no data thus no country was generated in the drop down list ,was retrieved ,no problem in the code above it work like charm.

Angular 2 observable issue

I am trying to get data on the basis of id which is set in url
working on add mode but getting error for edit
export class GradeComponent implements OnInit {
public isNew:boolean=true;
public frmGrade: FormGroup;
public subscription:any;
public oldGrade:Grade;
constructor(
private formBuilder:FormBuilder ,
private gradeService:GradeService,
private router:Router,
private activatedRoute:ActivatedRoute
) { }
ngOnInit() {
if(typeof this.activatedRoute.snapshot.params['id'] ==='undefined'){
this.frmGrade = this.formBuilder.group({
grade: ['', Validators.required],
description: ''
});
}else{
this.setForUpdate();
}
}
private setForUpdate(){
this.isNew=false;
this.gradeService
.getOneGrade(this.activatedRoute.snapshot.params['id'])
.subscribe(
data => {
this.oldGrade = data,
this.frmGrade = this.formBuilder.group({
grade: [this.oldGrade.grade, Validators.required],
description: this.oldGrade.description
});
},
err => console.error(err),
() => console.log('done')
);
}
but i am getting error
this.formBuilder is undefined how to handle this .
FormBuilder is a service Injectable, just get an instance with Dependancy Injection.
Add this in your class:
constructor(private formBuilder: FormBuilder) {}
And you are ready to go.
export class GradeComponent implements OnInit {
public isNew:boolean=true;
public frmGrade: FormGroup;
public subscription:any;
public oldGrade:Grade;
constructor(
private formBuilder:FormBuilder ,
private gradeService:GradeService,
private router:Router,
private activatedRoute:ActivatedRoute
) { }
ngOnInit() {
this.frmGrade = this.formBuilder.group({
grade: ['', Validators.required],
description: ''
});
if(typeof this.activatedRoute.snapshot.params['id'] !=='undefined') {
this.setForUpdate();
}
}
private setForUpdate(){
this.isNew=false;
this.gradeService
.getOneGrade(this.activatedRoute.snapshot.params['id'])
.subscribe(
data => {
this.oldGrade = data,
this.frmGrade = this.formBuilder.group({
grade: [this.oldGrade.grade, Validators.required],
description: this.oldGrade.description
});
},
err => console.error(err),
() => console.log('done')
);
}

Categories

Resources