У меня есть веб-страница, на которой отображается информация о зарегистрированном пользователе, которая вызывается из базы данных с использованием Spring REST API. Рядом с каждым свойством пользователя есть кнопка редактирования, при нажатии на которую отображается поле ввода, которое пользователь может использовать для редактирования этого свойства (пока что я добавил только поле пароля).
По какой-то причине после того, как я нажимаю кнопку и редактирую свойство, ничего не происходит, хотя в консоли должно отображаться «работает».
Вот метод контроллера Spring, который обрабатывает обновление:
@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!");
}
Вот метод обслуживания:
@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;
}
Класс EditUserProfileRequest:
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;
}
Вот html-код для поля пароля, который сначала отображает обычный пароль, а затем переходит к полям ввода после нажатия кнопки редактирования:
<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>
Вот мой мой компонент, который обрабатывает вызовы функции редактирования:
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.info(window.URL);
this.loginUser = JSON.parse(localStorage.getItem('currentUser'));
console.info(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.info('works');
}, err => {
console.info(err);
});
}
}
}
И, наконец, служба User с методом редактирования:
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);
}
}
Третий аргумент HttpClient.put() должен быть объектом опций. Обновите свой метод editUser
, чтобы вы передавали объект, содержащий ваш headers
, в качестве третьего аргумента вместо token
:
editUser(user, token): Observable<any> {
const headers = new HttpHeaders({'Authorization': 'Bearer ' + token});
return this.http.put('http://localhost:8082/myProfile/edit', user, { headers });
}
Надеюсь, это поможет!
Второй аргумент HttpClient.put() — это тело, третий аргумент — параметры. Вы называете это как
this.http.put('http://localhost:8082/myProfile/edit', user, token)
. Вы передаетеtoken
в качестве третьего аргумента вместо опций с заголовками. Я думаю, вы имеете в виду сделать что-то вродеthis.http.put('http://localhost:8082/myProfile/edit', user, { headers })
вместо этого. Пожалуйста, попробуйте хотя бы внести это изменение и дайте нам знать, если оно сработает.