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
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.