【问题标题】:fields in retrieved mysql database object are all undefined检索到的 mysql 数据库对象中的字段都是未定义的
【发布时间】:2017-11-03 15:47:25
【问题描述】:

我正在尝试使用 Angular 4 制作登录组件。在后端 Spring Boot 中,使用了 Spring Data Rest 和 MySQL 数据库。当我想使用检索到的帐户的登录凭据检查提交的登录详细信息时,我无法这样做,因为检索到的帐户对象中的所有字段都未定义,而对象本身未定义(我使用 if 结构进行检查)。有人可以看看我的代码并告诉问题出在哪里吗?我将从 Angular 4 类和服务开始,然后是帐户 pojo 和 Spring REST 存储库。

Angular 4 类:

import {Person} from "./Person";
import {Role} from "./Role";
export class Account {
  id: number;
  username: string;
  password: string;
  person: Person;
  roles: Role[];

}

export class LaborPeriod{
    id: number
    beginDate: Date
    endDate: Date
    hours: number
}

import {LaborPeriod} from "./LaborPeriod";
export class Person{
    id:number
    name:string
    laborPeriods:LaborPeriod[]
}


export class Role{
    id: number
    name: string
}

登录组件类:

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  providers: [AccountService]
})
export class LoginComponent {
  title: string;
  loginForm: FormGroup;

  constructor(private fb: FormBuilder,
              private accountService: AccountService,
              private router: Router) {
    this.title = "Inloggen";
    this.loginForm = fb.group({
      email: ['', [Validators.required, Validators.email]],
      password: ['', Validators.required]
    });
  }

  onSubmit() {
    const formModel = this.loginForm.value;

    const account: Account = this.accountService.authenticate(formModel.email, formModel.password);
    console.log(account.id + " " + account.password + " " + " " + account.username)
    console.log(account !== undefined)
    // if (account !== undefined) {
    //   this.router.navigate(["account/update", account.id]);
    // }
    // else{/*username or password doesent exist*/}
  }
}

accountservice中的相关方法

  authenticate(username: string, password: string): Account {
    return this.restapi.postCredentials(username, password);
  }

restApi:

@Injectable()
export class RestApiService {
  apiUrl: string = "/api/accounts";
  apiPostUrl: string = "api/accounts/search/findByUsernameAndPassword";
  data: Account;


  constructor(private http: Http) {}

  getData(){
    return this.http.get(this.apiUrl).map((res: Response) => res.json())
  }

  getContacts(){
    this.getData().subscribe(data=> {console.log(data); this.data = data})
  }

  postCredentials(username:string, password:string): Account {
    let params = new URLSearchParams();
    params.append("username", username);
    params.append("password", password);
    // params.set("username", "henk@gmail.com");
    // params.set("password", "12345");
    this.http.get(this.apiPostUrl, {params: params}).map((res: Response) => res.json()).subscribe(data=> { this.data = data});
    console.log(this.data);
    return this.data;
  }

}

现在一切都在后端

@Entity
public class Account {
    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private String password;
    @ManyToMany(cascade = CascadeType.ALL)
    private List<Role> roles;
    @OneToOne(cascade = CascadeType.ALL)
    private Person person;

@Entity
public class LaborPeriod {
    @Id
    @GeneratedValue
    private Long id;
    private Instant beginDate;
    private Instant endDate;
    private Integer hours;

@Entity
public class Role {
    //
    @Id
    @GeneratedValue
    private Long id;
    private String name;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    @OneToMany(cascade = CascadeType.ALL)
    private Collection<LaborPeriod> laborPeriods;

帐户存储库

@RepositoryRestResource
public interface AccountRepository extends JpaRepository<Account, Long> {
    Account findByUsername(@Param("username") String username);
    Account findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}

我们将不胜感激。

【问题讨论】:

  • 提供的答案如何?是否满足您的需求? :)
  • 是的,我搞定了。谢谢!
  • 太好了,很高兴听到! :) 如果任一答案对您有所帮助,请考虑接受一个答案,这会将问题标记为已解决 :)

标签: java angular spring-boot spring-data-rest


【解决方案1】:

您需要从您的发布请求中返回一个 Observable。这是异步,因此您的响应在您的回调中可用。即使您尝试从您的回调subscribe 中执行此操作,这也是不可能的,因为这又是异步的。所以你需要从你的 post 请求中返回一个 Observable:

return this.http.get(this.apiPostUrl, {params: params})
  .map((res: Response) => res.json())

在这里,您实际上可以跳过 authenticate 方法,我看不出它对您有什么用处。但如果你想保留它,当然可以:)

那么你接下来要做的就是在你的组件中订阅这个发布请求。

constructor(private restApiService: RestApiService /** **/) { }

onSubmit() {
  const formModel = this.loginForm.value;
  this.restApiService.postCredentials(formModel.email, formModel.password);
    .subscribe(.....)
}

值得一读:How do I return the response from an Observable/http/async call in angular2?

【讨论】:

    【解决方案2】:

    使用 interface 代替 class 并将您的响应类型转换如下,

    getData(){
        return this.http.get(this.apiUrl).map((res: Response) => <Account> res.json())
      }
    

    注意:如果你使用类,你应该有一个构造函数来设置属性。

    【讨论】:

    • 您好,为什么我的帐户类需要构造函数?我不能简单地使用 point(.) 运算符来设置字段吗? (例如 account.username = 'test'。
    • 可以但需要实例化对象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多