Delivering JSON-formatted API responses from C# to Angular

When retrieving data from an API and attempting to parse it as JSON in Angular ts, the following error occurs: "Argument of type 'Subscription' is not assignable to parameter of type 'string'". The desired outcome is to receive the JSON response from the API in the format [{name:"name1"},{name:"name2"}] instead of [{"name":"name1"},{"name":"name2"}], as the latter does not properly write the name on the CSV file.

[HttpGet("getEmployees")]
[ProducesResponseType(200, Type = typeof(IEnumerable<EmployeesView>))]
public async Task<IActionResult> GetEmployeesByCreateDate(DateTime period)
{

try
{
// Read model returns users based on a logic as enumerable
return Ok(await _readModel.GetEmployees(period));
}
catch (Exception e)
{
// Throw exception
}

myService.ts


getAllPosts() {
  return this.http.get<IEmployee[]>(this.URL).subscribe((data: any) => {return data;});
}
  
download(data, filename='data') { 
let csvData=this.ConvertToCSV(data, ['name1','name2']); 
let blob = new Blob(['\ufeff' + csvData],{type:'text/csv;charset=utf8;'}); 
let dwldLink = document.createElement("a");
let url = URL.createObjectURL(blob);
dwldLink.setAttribute("href", url);
dwldLink.setAttribute("download", filename + ".csv");
dwldLink.style.visibility = "hidden";
document.body.appendChild(dwldLink); 
dwldLink.click();
}

ConvertToCSV(objArray, headerList) {
let array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
let str = '';
let row = 'S.No,';
for (let index in headerList) {
  row += headerList[index] + ',';
}
row = row.slice(0, -1);
str += row + '\r\n';
for (let i = 0; i < array.length; i++) {
  let line = i + 1 + '';
  for (let index in headerList) {
    let head = headerList[index];
    line += ',' + array[i][head];
  }
  str += line + '\r\n';
}
return str;
}

myComponent.ts

JsonData = JSON.parse( this.URL.getAllPosts());
      
download2(){ this.URL.download(this.JsonData, 'jsontocsv'); } //here is the problem 

The desired formatting of the returned data is:

[{"name":"name1", "surname":"surname1"}, {"name":"name2", "surname":"surname2"}]

However, the current output appears as follows (the desired structure is needed for downloading as CSV):

[{"name":"name1", "surname":"surname1"}, {"name":"name2", "surname":"surname2"}]

Answer №1

When you call the subscribe() method, it returns a Subscription object that allows you to unsubscribe later. The actual data is not returned by subscribe(); instead, it saves your callback function for execution once a response is received. For simple HTTP requests, unsubscribing is typically unnecessary as they complete after the first response.

You have the option to perform actions within your callback function or utilize async, await, and firstValueFrom() to achieve code that appears more synchronous.

Additionally, there's no need to manually parse the data since this is handled automatically by the HttpClient service.

async getAllPosts(): Promise<IEmployee[]> {
    return await firstValueFrom(this.http.get<IEmployee[]>(this.URL));
}
JsonData = await this.URL.getAllPosts();

Alternatively

getAllPosts(): Observable<IEmployee[]> {
    return this.http.get<IEmployee[]>(this.URL);
}
this.URL.getAllPosts().subscribe((data) => JsonData = data);

If you make the suggested edits, this solution should meet your needs:

In your service

async getAllPosts(): Promise<IEmployee[]> {
    return await firstValueFrom(this.http.get<IEmployee[]>(this.URL));
}

In your component

async download2() { 
  this.URL.download(await this.URL.getAllPosts(), 'jsontocsv'); 
}

Another issue I noticed with your download function is:

let csvData = this.ConvertToCSV(data, ['name1','name2'])

This line should actually be:

let csvData = this.ConvertToCSV(data, ['name', 'surname']);

To use callbacks instead of promises:

In your service

getAllPosts(): Observable<IEmployee[]> {
    return this.http.get<IEmployee[]>(this.URL);
}

In your component

download2() { 
  this.URL.getAllPosts().subscribe((data) => this.URL.download(data, 'jsontocsv')); 
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extract the array structure from the resolved promises using await with Promise.all()

When I receive the values returned by using await Promise.all() in the following manner: const [apple, banana] = await Promise.all<Object, Object>([ applePromise(), bananaPromise() ]).catch(error => next(error)); An error is triggered: T ...

The functionality of Angular 2 md-radio buttons in reactive forms seems to be hindering the display of md-inputs

Currently, I am following the instructions for implementing reactive form radio buttons on a project using Angular 2.1.2 and Google's MD-alpha.10 Atom-typescript shows no errors in my code. However, when testing the application, I encountered the foll ...

Import the Excel sheet into a DataTable, ensuring that only the initial 256 characters of each cell are captured

I am facing an issue with loading an excel sheet into a datatable using OleDb. The sheet has a multiline text column that can contain up to 1000 characters. After importing the data using the code below, I noticed that each cell in my DataTable only holds ...

The StreamingTextResponse feature is malfunctioning in the live environment

When I share my code, it's an API route in Next.js. In development mode, everything works as expected. However, in production, the response appears to be static instead of dynamic. It seems like only one part of the data is being sent. I'm puzzl ...

Connect your Windows 10 computer to a device and effortlessly stream audio via Bluetooth using the 32feet library

Is there a way to stream audio from a smartphone to the computer speakers on Windows 10? I have successfully connected the two devices using a Bluetooth headset service. However, even though the smartphone's sound is muted due to the Bluetooth connect ...

Changing the child component input in Angular's deep cloning cannot be reflected on the user interface

I am currently working on a parent-child component setup. Within the parent component, I have a BehaviourSubject<SomeObject[]>(). export interface SomeObject(){ field: number; ... editable: boolean } Before passing the object to the child component, ...

Alerts in Angular templates of inherited class in WebStorm

While working with WebStorm 2019.3.2, I have noticed some warnings in Angular templates: https://example.com/image.png This is happening because the properties are being initialized on the parent component instead of the child. @Component({ selector: ...

Using Observable.subscribe in Angular 8 empties my user class

Just starting out with Angular and I have a question about making API calls. GetUserDetailsfromID(id:number):Observable<UserResponse> { let token = localStorage.getItem("userToken"); return this.http.get<UserResponse>(this.base ...

Encountered an issue when accessing a C# Webservice via AJAX - returning a Dataset as the output

This is my initial exposure to C# Web Service & AJAX. I am interested in creating a page similar to Facebook, where the next set of records loads as we scroll down. Although I have attempted to implement the code, it is not functioning as expected. Can an ...

Having difficulty with C# regular expressions

string text = "AT + CMGL =\"REC UNREAD\"\r\r\n+CMGL: 5,\"REC UNREAD\",\"+420733505479\",\"\", \"2015/09/08 13:38:31+08\"\r\nPrdel\r\n\r\nOK\r\n"; Regex ...

Sending optional data in Angular routesIn Angular, you can include additional

In my project utilizing angular 5, I have a lengthy routing file: const homeRoutes: Routes = [ { path: 'home', component: HomeComponent, children: [ { path: 'registration', component: RegistrationCompone ...

Implementing JSON WebService on WP7 to Save Images in Database

I'm having trouble saving images in a database using a JSON web service without actually saving the image data itself. When I try to send the image byte, it doesn't save. Can anyone guide me on how to properly send or receive an image with a JSON ...

Adjust the dimensions of the Rectangle to fit a new size

When working with Windows Forms, I am capturing a full-size screenshot of a specific window with predetermined dimensions. The captured image is saved into a Bitmap object and then I use a Rectangle structure to crop a specific region of the screenshot for ...

Is it feasible to utilize GraphQL subscriptions with Azure Functions?

Exploring the potential of implementing GraphQL subscriptions on Azure Functions. Unfortunately, it seems that apollo-server-azure-functions may not be compatible. Are there any other options or strategies to successfully enable this functionality? ...

Navigating Angular with relative paths: A guide to locating resources

Here is the structure of my app: index.html main.ts app |--main.component.html |--main.component.ts |--app.module.ts |--note.png ... etc I am trying to include the note.png file in main.component.html which is located in the same folder. I have att ...

Tips for accurately typing a "Type Mapping" function

In my code, I have a specific type designed for a function that takes one type I as input and returns another type O as output. Here is how it currently looks: export interface IFunctionalMapping<I, O, K extends keyof O> { [prop: Extract<O[K], ...

Extending the Object prototype within an ES6 module can lead to errors such as "Property not found on type 'Object'."

There are two modules in my project - mod1.ts and mod2.ts. //mod1.ts import {Test} from "./mod2"; //LINE X interface Object { GetFooAsString(): string; } Object.prototype.GetFooAsString = function () { return this.GetFoo().toString(); } //mod2. ...

Ways to enable Urql (typescript) to accept Vue reactive variables for queries generated using graphql-codegen

I'm currently developing a Vue project that involves using urql and graphql-codegen. When utilizing useQuery() in urql, it allows for the use of Vue reactive variables to make the query reactive and update accordingly when the variables change. The ...

Angular's detectChanges function does not trigger the ngDoCheck method

When I run cdr.detectChanges() in a nested child component (Child1) which has a parent and another nested child component (Child2), only ngDoCheck is invoked in Child2. Why doesn't it invoke DoCheck in the current component (Child1) as well? How can I ...

Finding the number enclosed within two characters - TypeScript

Recently, I've started exploring Typescript and I'm currently working on creating a webhook within my Google Cloud Functions. In one of the scenarios, I have this string: C1234567890A460450P10TS1596575969702 My objective is to utilize regex to ...