Reputation: 545
I have a webpage that displays a logged in user information which is called from database using a spring REST API. Next to each user property there's an edit button when clicked displays an input field which the user can use to edit that property (I've only added it the password field so far).
For some reason after I click on the button and edit the property nothing happens even though it's supposed to display 'works' in the console.
Here's the spring controller method that handles the update:
@PutMapping("myProfile/edit")
public ResponseEntity<Object> updateProfile(@CurrentUser User currentUser, @RequestBody EditUserProfileRequest user){
User updatedUser = userService.updateProfile(currentUser, user);
return ResponseEntity.ok().body("Update Success!");
}
Here's the service method:
@Override
public User updateProfile(User currentUser, EditUserProfileRequest input) {
User user = this.getUserByUsername(currentUser.getUsername());
user.setEditedProfile(input);
if(input.getPassword()!=null){
user.setPassword(passwordEncoder.encode(input.getPassword()));
}
User saveMe = userRepository.save(user);
return saveMe;
}
The EditUserProfileRequest class:
package com.example.demo.contract;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class EditUserProfileRequest {
private String firstName;
private String lastName;
private String password;
private String email;
private String location;
private String bio;
private Long phoneNumber;
private Long zipCode;
}
Here's the html code for the password field which would display the normal password first then change to input fields after clicking on the edit button:
<div style="margin-top: 3px; margin-bottom: 3px;">
<h5 style="float: left; margin-left: 160px; margin-top: 18px;">
<b>Password: </b>
</h5>
<div id="hashPassword" style="display: block">
<div style="width: 100px; margin-left: 233px; float: left;">
<span style="font-weight: 600">*********</span>
</div>
<mat-icon id="hashPassword" aria-label="EDIT" aria-hidden="false" (click)="editPassword()" style="cursor: pointer; margin-left: 446px">edit</mat-icon>
</div>
<div id="editPassword" style="display: none">
<div style="width: 800px; margin-left: 233px; float: left;">
<form [formGroup]="passwordEditForm" (ngSubmit)="onPasswordSubmit()">
<div class="form-group">
<label>Password</label>
<input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.minlength">Password must be at least 4 characters</div>
</div>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }" />
<div *ngIf="submitted && f.confirmPassword.errors" class="invalid-feedback">
<div *ngIf="f.confirmPassword.errors.required">Confirm Password is required</div>
<div *ngIf="f.confirmPassword.errors.mustMatch">Passwords must match</div>
</div>
</div>
<div class="form-group">
<button type="button" class="btn btn-primary">Confirm Edit</button>
</div>
</form>
</div>
</div>
</div>
Here's my my component that handles the calls the edit function:
import { Component, OnInit, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MediaMatcher } from '@angular/cdk/layout';
import { Router } from '@angular/router';
import { DomSanitizer } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { HttpHeaders, HttpClient } from '@angular/common/http';
import { MustMatch } from '../must-match.validators';
import { UserService } from '../user.service';
@Component({
selector: 'app-myacc',
templateUrl: './myacc.component.html',
styleUrls: ['./myacc.component.scss']
})
export class MyaccComponent implements OnInit {
loginUser: any = {};
imgSrc: any;
submitted = false;
passwordEditForm: FormGroup;
constructor(private router: Router,
private sanitizer: DomSanitizer,
private http: HttpClient,
private fb: FormBuilder,
private service: UserService) {
}
ngOnInit() {
console.log(window.URL);
this.loginUser = JSON.parse(localStorage.getItem('currentUser'));
console.log(this.loginUser);
this.passwordEditForm = this.fb.group({
password: ['', [Validators.required, Validators.minLength(4)]],
confirmPassword: ['', Validators.required]
}, {
validator: MustMatch('password', 'confirmPassword')
});
}
editPassword() {
document.getElementById('hashPassword').style.display = 'none';
document.getElementById('editPassword').style.display = 'block';
}
get f() {
return this.passwordEditForm.controls;
}
onPasswordSubmit() {
this.submitted = true;
if (this.passwordEditForm.invalid) {
return;
} else {
this.service.editUser(this.passwordEditForm.value, this.loginUser.token).subscribe(res => {
console.log('works');
}, err => {
console.log(err);
});
}
}
}
And finally the User service that has the edit method:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) {
this.http = http;
}
getAllUsers(token: any): Observable<any> {
// tslint:disable-next-line: object-literal-key-quotes
const headers = new HttpHeaders({'Authorization': 'Bearer ' + token});
return this.http.get('http://localhost:8082/users', {headers: headers});
}
getUser(token: any): Observable<any> {
// tslint:disable-next-line: object-literal-key-quotes
const headers = new HttpHeaders({'Authorization': 'Bearer ' + token});
return this.http.get('http://localhost:8082/getuser', {headers: headers});
}
getAllOffer(): Observable<any> {
return this.http.get('http://localhost:8082/getAllOffer');
}
getServices(): Observable<any> {
return this.http.get('http://localhost:8082/services');
}
editUser(user, token): Observable<any> {
const headers = new HttpHeaders({'Authorization': 'Bearer ' + token});
return this.http.put('http://localhost:8082/myProfile/edit', user, token);
}
}
Upvotes: 1
Views: 802
Reputation: 38827
The third argument of HttpClient.put() should be an options object. Update your editUser
method so that you are passing an object containing your headers
as the third argument instead of token
:
editUser(user, token): Observable<any> {
const headers = new HttpHeaders({'Authorization': 'Bearer ' + token});
return this.http.put('http://localhost:8082/myProfile/edit', user, { headers });
}
Hopefully that helps!
Upvotes: 1