1

I have a REST API returning a Hashmap <String,<String,Integer>>. I need to use this Hashmap Json to display a table in Angular 5. I have tried the following till now, but the table is still empty. I am not very sure how to access the nested object in the model class properly in the HTML File. Where am I going wrong?

This is the frequency-table.model.ts file where I have defined the structure of the HashMap.

export interface FrequencyTable {
obj: {
    key: String;
    val: {
        key_in: String;
        val_in: Number;
    };
} 
}

This is the HTML File

<div class="container">
<div class="row">
    <table class="table">
        <thead class="thead-inverse">
        <tr>
            <th class="text-center">Thread Name</th>
            <th class="text-center">Query</th>
            <th class="text-center">Frequency</th>

        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let post of _postsArray">
            <td class="text-center" style="width: 15px;">{{post.key}}</td>
            <td class="text-center" style="width: 15px;">{{post.val.key_in}}</td>
            <td class="text-center" style="width: 200px;">{{post.val.val_in}}</td>

        </tr>
        </tbody>
    </table>
</div>

This is the frequency-table.component.ts file

export class FrequencyTableComponent implements OnInit {
  _postsArray: FrequencyTable[];

 constructor(private tableService: TableService) { }
 getPosts(): any {
  this.tableService.getPosts()
    .subscribe(
        resultArray => this._postsArray = resultArray,
        error => console.log("Error :: " + error)
    )
 }

  ngOnInit() {

  }

This is the service.ts file

@Injectable()
export class TableService {

constructor(private http: HttpClient) {}
getPosts(): Observable<FrequencyTable[]> {
return this.http
    .get('\getQueryCount')
    .map((response: Response) => {
        return <FrequencyTable[]>response.json();
    })
    .catch(this.handleError);
   }

    private handleError(error: Response) {
    return Observable.throw(error.statusText);
  }
  }

This is the REST API returning Hashmap json:

@RestController
public class QueryCounterController{

@Autowired
ReadFileService rfservice;


@GetMapping("/getQueryCount")
@ResponseBody
public Map<String, Object>  getQueryCount() throws IOException{

String filename = "file.txt";

return (rfservice.readFile(filename));}

}

Sample Json:

 {
     "key1": {
     "xyz": 3,
     "abc": 2
     },
     "key-2": {
     "pqr": 3,
     "uvw": 2
     }
  }

6
  • One of things that may go wrong is in var obj = this.getPosts(); - this line of code returns immediately without waiting for the http request to complete. You should move your logic inside subscribe function. Commented Apr 3, 2018 at 8:44
  • I removed the code for ngOnInit(). It still doesn't work Commented Apr 3, 2018 at 8:54
  • @apoorva96, your response conversion in angular app is invalid. You are not sending list of objects as a response. You are sending map means only one object. So, convert your response to list of objects as you like in service.ts Commented Apr 3, 2018 at 9:00
  • @swarooppallapothu could you explain it with some code please Commented Apr 3, 2018 at 9:02
  • 1
    @apoorva96, you can do in 2 ways. #1. change return type in java as List<Object> instead of Map<String, Object>. #2. convert your response in service.ts as list of objects like FrequencyTable Commented Apr 3, 2018 at 9:07

2 Answers 2

1

I have solved the problem by making the following changes:

frequency-table.component.ts

export class FrequencyTableComponent implements OnInit {
_postsArray: Array<any> = [];
 constructor(private tableService: TableService) { }

 ngOnInit() {

  this.tableService.getPosts().subscribe((data: any) => {
  console.log(data);
   Object.keys(data).forEach(key => {
    var obj1 = data[key];
    console.log('key is ' + key);
     Object.keys(obj1).forEach(key1 => {
      console.log('key inner is ' + key1 + ' val is ' + obj1[key1]);
      this._postsArray.push({k: key, l: key1, m: obj1[key1]});
    })
  });
  console.log('array is ' + this._postsArray.toString());

   });
  }

frequency-table.service.ts

@Injectable()
export class TableService {

constructor(private http: HttpClient) {}
getPosts(): any {
return this.http.get('/getQueryCount');
}

frequency-table.component.html

<div class="container">
<div class="row">
    <table class="table">
        <thead class="thead-inverse">
        <tr>
            <th class="text-center">Thread Name</th>
            <th class="text-center">Query</th>
            <th class="text-center">Frequency</th>

        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let post of _postsArray">
            <td class="text-center" style="width: 15px;">{{post.k}}</td>
            <td class="text-center" style="width: 15px;">{{post.l}}</td>
            <td class="text-center" style="width: 200px;">{{post.m}}</td>

        </tr>
        </tbody>
    </table>
</div>

I have removed frequency-service.model.ts class for the time being. Now I am getting the table as desired. Thanks @SEY_91 for your help.

Sign up to request clarification or add additional context in comments.

Comments

0

getPosts is returning an Observable of map:

  ngOnInit(){
    this.getPosts().subscribe(obj => {
      Object.keys(obj).forEach(key => {
        this._postsArray.push({obj: {key: key, val : { key_in:obj[key].key, val_in :obj[key].val}}});
      });
    });
  }

Html:

<tr *ngFor="let post of _postsArray">
            <td class="text-center" style="width: 15px;">{{post.obj.key}}</td>
            <td class="text-center" style="width: 15px;">{{post.obj.val.key_in}}</td>
            <td class="text-center" style="width: 200px;">{{post.obj.val.val_in}}</td>

        </tr>

6 Comments

shouldn't it be obj.key in the last line?
you mean {obj: {key: key, val : obj[key] } } ??
add the structure of the json response maybe I could figure out the problem
how should I access this in HTML now?
I tried to parse the response the same way you did it in ngOnInit before editing the question, otherwise I have no idea how the json response structure is
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.