I’m trying to use Angular and Spring Boot to show a list of Rule objects. I am not using a JPA Repository to respond to the GET request, so I think I have to ‘manually’ convert my list of Rule objects on the Spring Boot side to a JSON so that httpClient.get<Rule[]>()
can convert it to a list of Rule objects on the Angular side. However, this is currently not working, and my rule objects are not showing up on my webapp.
I’m not using a repository because I’m querying the database on the Spring Boot side, and doing some business logic to only display rules that fall under a certain criteria, and adding some information about the rules that is not in the database.
How do I correctly convert the list of rules to a JSON? Is this even the right approach?
Thank you!
Rule.java:
@Entity @Table(name = "MSG_DOM") public class Rule implements Serializable{ private static final long serialVersionUID = 1L; private String fireType; private boolean multipleDrivers; @Id @Column(name = "MSG_CD", unique = true, nullable = false) private String messageCode; @Column(name = "MSG_TYP_CD", unique = false, nullable = false) private String messageTypeCode; @Column(name = "BUS_RUL_CD", unique = false, nullable = false) private String busRuleCode; @Column(name = "MSG_EXTR_USER_TXT", unique = false, nullable = false) private String externalMessageText; @Column(name = "MSG_INTRL_USER_TXT", unique = false, nullable = false) private String internalMessageText; public Rule(){} public String getMessageCode(){ return messageCode; } public void setMessageCode(String messageCode){ this.messageCode = messageCode; } ...
RuleController.java:
@RestController @RequestMapping("/api/v1") public class RuleController { //get all rules @CrossOrigin(origins = "http://localhost:4200") @RequestMapping(value = "/rules", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE}) @ResponseBody public Rule[] getAllRules() { RuleListService ruleListService = new RuleListService(); List<Rule> ruleList = ruleListService.listRules(); Rule[] rules = new Rule[ruleList.size()]; for (int i = 0; i < ruleList.size(); ++i) rules[i] = ruleList.get(i); return rules; } }
RuleListService.java:
public class RuleListService { ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); public List<Rule> listRules() { RuleList lister = context.getBean(RuleList.class); ArrayList<HashMap<String, Rule>> ruleMaps = lister.loadRuleMap(); ArrayList<Rule> ruleList = new ArrayList<Rule>(); for(HashMap<String, Rule> ruleMap: ruleMaps) { ruleList.addAll(ruleMap.values()); } return ruleList; } }
rule.ts:
export class Rule { constructor( private _serialVersionUID : number, private _fireType: string, private _multipleDrivers: boolean, private _messageCode: string, private _messageTypeCode: string, private _busRuleCode: string, private _externalMessageText: string, private _internalMessageText: string,) { } getSerialVersionUID() : number { return this._serialVersionUID; } setSerialVersionUID(value: number) { this._serialVersionUID = value; } ...
rule.service.ts:
@Injectable({ providedIn: 'root' }) export class RuleService { private baseUrl = "http://localhost:8080/api/v1/rules" constructor(private httpClient: HttpClient) {} getRuleList(): Observable<Rule[]> { return this.httpClient.get<Rule[]>(`${this.baseUrl}`).pipe( catchError(this.handleError) ); } private handleError = (error: Response) => { if (error.status === 400) { return throwError(() => new Error("Bad Input")); } if (error.status === 404) { return throwError(() => new Error("Not Found")); } return throwError(() => new Error("App Error")); } }
rule-list.component.ts:
export class RuleListComponent implements OnInit { rules: Rule[]; ruleTest: Rule; constructor(private ruleService: RuleService) { } ngOnInit(): void { this.getRules(); } private getRules() { this.ruleService.getRuleList().pipe( map((actions: Rule[]) => actions.map(action => { return action as Rule;} ) )).subscribe(rules => this.rules = rules); } }
rule-list.component.html:
<h2> Rule List </h2> <table class = "table table-striped"> <thead> <tr> <th> MSG_CD </th> <th> MSG_TYP_CD </th> <th> BUS_RUL_CD </th> <th> MSG_EXTR_USER_TXT </th> <th> MSG_INTRL_USER_TXT </th> <th> Fire Type </th> <th> Multiple Drivers </th> </tr> </thead> <tbody> <tr *ngFor = "let rule of rules" > <td> {{rule.getMessageCode()}} </td> <td> {{rule.getMessageTypeCode()}} </td> <td> {{rule.getBusRuleCode()}} </td> <td> {{rule.getExternalMessageText()}}</td> <td> {{rule.getInternalMessageText()}} </td> <td> {{rule.getFireType()}} </td> <td> {{rule.getMultipleDrivers()}} </td> </tr> </tbody> </table>
UPDATE: I’m still not seeing the data in the table, and have gotten this error from the dev console on my browser:
ERROR TypeError: rule_r1.getMessageCode is not a function at RuleListComponent_tr_20_Template (rule-list.component.html:16:18)
I tried changing the variables to public in the Rule.ts constructor, and accessing the variables directly instead of calling get() methods like so, {{rule._messageCode}}, for all table fields, and while it (obviously) got rid of the error, I still did not see data in the table.
The table has been populated with rows indicating there is actually a Rule[] being sent and received correctly, but there is no data in any row.
I’ve also updated all included code, since many changes have been made.
Advertisement
Answer
Posting as an answer not an update in order to help anyone who has the same issue.
- Moved attributes of Rule object out of constructor in Rule.ts
- Per @BeWu’s suggestion, got rid of the “_” prepending the attribute names in Rule.ts
- Changed getRules() in rule-list.component.ts to:
private getRules() { this.ruleService.getRuleList().subscribe( res => { this.rules = res.map(x => Object.assign(new Rule(), x));
My table is now displaying all values correctly. I think the issue was stemming from the getRules() method not properly converting the data from ruleService.getRuleList() into Rule objects. I found a similar question with a great answer that had lots of useful information, linked here.
Thank you to everyone who took the time to post suggestions and guidance!