1

I get the data from API end point as below

actual value

But the output I expect is just an array of object which is like

[{Crqnumber: "CRQ000000135318",
  approvalstatus: "Approved",
  changecoordinator: "Sariga Suresh",
  productname: "MSS (NextGen)",
  status: "Closed",
  statusreason: "Successful"},
 {Crqnumber: "CRQ000000135318",
  approvalstatus: "Approved",
  changecoordinator: "Sariga Suresh",
  productname: "MSS (NextGen)",
  status: "Closed",
  statusreason: "Successful"},
 {Crqnumber: "CRQ000000135318",
  approvalstatus: "Approved",
  changecoordinator: "Sariga Suresh",
  productname: "MSS (NextGen)",
  status: "Closed",
  statusreason: "Successful"}]

I decide to use pipe() and map() for achieving this, but I am stuck. I could not achieve the expected out.

my service is

export class CrqData{

constructor(private http: HttpClient){}

getCrqList(){
    return this.http.get<Crq[]>('http://d7598:8000/crqlist/').pipe(map((responseData=>{
        let temp: Crq[]=[];
        temp=responseData;
        return temp
    })));
}
}

my component ts file

export class CrqComponent implements OnInit {

crqList = [];

constructor(private crqData:CrqData) { 
this.crqData.getCrqList().subscribe((data)=>{
  console.log(data)
}, (error)=>{
  console.log(error);
});
}

ngOnInit() {
}

}

my component html

<mat-card style="padding: 1.5%; margin: 1%;" *ngFor="let crq of crqList">
<mat-card-content>
  <div style="line-height: 20px;">
      <div style="float: left; font-weight: bold;">
          <p>CRQ No: {{crq.Crqnumber}}</p>
      </div>
      <div style="float: right; font-weight: bold;">
          <p style="float: left;padding-top: 1px;">
              <i class="material-icons" style="font-size: 12px;">fiber_manual_record</i>
          </p>
          <p style="float: right;">{{crq.approvalstatus}}</p>
      </div>
  </div>
  <div style="clear: both; line-height: 6px; font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;">
      <p style="text-align: left;">Change coordinator: {{crq.changecoordinator}}</p>
      <p style="text-align: left;">Title: {{crq.productname}}</p>
  </div>
</mat-card-content>
</mat-card>

my object is

export interface Crq{
    Crqnumber: string;
    approvalstatus: string;
    changecoordinator: string;
    productname: string;
    status: string;
    statusreason: string;
}
James Z
  • 12,209
  • 10
  • 24
  • 44
Dev Anand
  • 314
  • 1
  • 14

3 Answers3

1

First of all, you should change your type in the http.get call. You're not recieving a Crq[], you're receiving an object which contains 3 properties, where one property (results) is of the type Crq[].

So you should define a type which holds all these 3 properties, like this: (you can put this above the line export class CrqData {)

interface CrqResponse {
    count: number;
    error: number;
    results: Crq[];
}

Now, you can use this in your http request and use the response, like this:

getCrqList(){
    return this.http.get<CrqResponse>('http://d7598:8000/crqlist/').pipe(map((responseData=>{
        return responseData.response;
    })));
}

I'd also suggest that you throw an error if the error property is not equal to 0, so that instances that use your service can catch the error if there is one. So getCrqList() should look something like this:

getCrqList() {
     return this.http.get<CrqResponse>('http://d7598:8000/crqlist/').pipe(switchMap((responseData=>{
        if(responseData.error !== 0) {
            return throwError(responseData.error);
        }
        else {
            return of(responseData.response);
        }
    })));
ShamPooSham
  • 2,301
  • 2
  • 19
  • 28
  • glad I could help :) – ShamPooSham Mar 14 '20 at 11:50
  • But switchMap() is something new to me. May I know some sites where I could be able to learn about all the rxjs operators? – Dev Anand Mar 14 '20 at 11:54
  • A lot of the rxjs documentation can be quite abstract since they don't only talk about calls from HttpClient, but observables in a larger context which can be used in many other ways (emitting multiple values and not completing automatically like HttpClient does). So sorry, I don't have any good resource. But I can try to explain what's going on – ShamPooSham Mar 14 '20 at 13:21
  • 1
    The issue with using map instead of switchMap in this case is that the rxjs function throwError returns an Observable in itself, so that would mean that the return type of `getCrqList()` would be `Observable>`. By using switchMap, we make sure that the result of throwError is evaluated before it's being sent to the next step of the outer Observable. However, this means that we can't just return `responseData.response` in the other case because switchMap expects the result of the inner function to be an Observable. That's why I wrap the result with `of` to return an Observable – ShamPooSham Mar 14 '20 at 13:30
  • @DevAnand Thinking about it, maybe `mergeMap` is better than `switchMap` in the general case of using observables, but it doesn't really matter in the case of using HttpClient. – ShamPooSham Mar 14 '20 at 13:31
  • Thank you for your explanation. Got some idea about switchMap() – Dev Anand Mar 15 '20 at 10:30
0

I think you have to get results property from the response so you have to modify this method to be like this

export class CrqData{

constructor(private http: HttpClient){}

getCrqList(){
    return this.http.get<Crq[]>('http://d7598:8000/crqlist/').pipe(map((responseData=>{
        const { results } =responseData;
        return results
    })));
}
}
Ahmed Kesha
  • 810
  • 5
  • 11
  • That would give you a type error by typescript, because `responseData` is defined to be `Crq[]`. You need to define a new type first – ShamPooSham Mar 14 '20 at 11:49
0

I found the answer. I should have my service class as below

export class CrqData{

constructor(private http: HttpClient){}

getCrqList(){
    return this.http.get<Crq[]>('http://d7598:8000/crqlist/').pipe(map((responseData=>{
        let temp: Crq[]=[];
        for(let data in responseData){
            for(let d in responseData[data]){
                console.log(responseData[data][d]);
                temp.push(responseData[data][d]);
            }
        }
        return temp
    })));
}
}
Dev Anand
  • 314
  • 1
  • 14