Reputation: 92
I am working on a JHipster application, I have a Study entity which has a many-to-one relationship with User (So one user can have many studies). I am trying to change the user select in the dialog component for creating a new Study to automatically select the current logged in user.
I have changed the select so that only the single user should show up as an option for the select, after fixing this issue I would either disable the field or remove it so that study.user is automatically set:
<select class="form-control" id="field_user" name="user [(ngModel)]="study.user" >
<option [ngValue]="user.id === study.user?.id ? study.user : user">{{user.login}}</option>
</select>
The userService is queried though:
this.userService.query()
.subscribe((res: ResponseWrapper) => { this.user = res.json; }, (res: ResponseWrapper) => this.onError(res.json));
Which runs this query to the api in user.service.ts:
private resourceUrl = 'api/users';
...
query(req?: any): Observable<ResponseWrapper> {
const options = createRequestOption(req);
return this.http.get(this.resourceUrl, options)
.map((res: Response) => this.convertResponse(res));
}
The GET method in UserResource.java:
@GetMapping("/users")
@Timed
public ResponseEntity<UserDTO> getAllUsers() {
return ResponseUtil.wrapOrNotFound(
userService.getAllManagedUsers()
.map(UserDTO::new));
}
Which calls this method in UserService.java:
@Transactional(readOnly = true)
public Optional<User> getAllManagedUsers() {
return userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin());
}
findOneByLogin is defined in userRepository, the Spring Data JPA repository for the User entity.
My issue is that when I try to access the user object from my entity, it is undefined, throwing errors such as:
ERROR TypeError: Cannot read property 'id' of undefined
Upvotes: 0
Views: 6801
Reputation: 505
I did something similar: In xxxResource.java:
public String getCurrentUserLogin() {
org.springframework.security.core.context.SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String login = null;
if (authentication != null)
if (authentication.getPrincipal() instanceof UserDetails)
login = ((UserDetails) authentication.getPrincipal()).getUsername();
else if (authentication.getPrincipal() instanceof String)
login = (String) authentication.getPrincipal();
return login;
}
then before xxxRepository.save add:
User user=new User();
user=UserRepository.findOneByLogin(getCurrentUserLogin()).get();
Order.setUser(user);
See https://codefitter2.blogspot.com/2016/12/how-to-add-user-to-new-record-in.html
Upvotes: 2
Reputation: 16294
If I understood correctly, you have a Study which has a relationship with User and when you retrieve a Study object: study.user is undefined in your problem in angular code.
You can't trust angular code, so User selection cannot be in client when creating a Study, so you should ignore it in StudyMapper (assuming you use DTOs) or StudyService should overwrite it.
JHipster creates views and APIs that are for administrators. In your case you want to build an API for simple users who are only allowed to manage their own studies, if you try to address both use cases in same classes your code could get messy and you may introduce security flaws. So I'd suggest that you split the 2 APIs and probably views unless you want to drop the admin part. By having StudyResource on/api/study for admins and MyStudyResource on /api/user/study, you can protect them differently by role and avoid the issues you have in view because you'll have a well-defined context rather than putting if/then/else all a round.
Another reason to do so is that it makes easier to upgrade JHipster generated code using jhipster upgrade
command.
JHipster does not design your API because it does know about your business domain. It provides you with a CRUD interface to manage data above a REST API and entities from a technical standpoint. This is why it maps one resource per entity rather than aggregates which are what you end up with when you analyze your business domain using DDD. Aggregates are better also in terms of performance especially for mobile clients because you end up making less API calls.
You could also add an API using https://github.com/cbornet/generator-jhipster-swagger-api-first
Upvotes: 5