Angular Component fails to Parse API Results

Stimulsoft Ultimate discussion
Post Reply
jwcurnalia
Posts: 2
Joined: Wed Sep 23, 2020 3:40 pm

Angular Component fails to Parse API Results

Post by jwcurnalia »

As a first step to implementing the new Angular component in our application I set up a simple test API to get an idea of how everything would hang together. I used the example code from the Get Started page as a base.

When the component received the output from the API it failed to parse as it was expecting a completely different structure. I was able to get it to work but had to actually rewrite the parsing code:

Original Code:

Code: Select all

        ControllerService.prototype.loadViewer = function () {
            var _this = this;
            var url = this.model.requestUrl.replace('{action}', this.model.action);
            this.httpClient.post(url, this.model.createPostParameters({ action: 'AngularViewerData' }, true, false), 'json').subscribe(function (data) {
                _this.model.clear();
                _this.stylesService.setupStyle(atob(data['styles']), 'viewer');
                _this.model.options = data;
                _this.checkTrExp();
                _this.initAutoUpdateCache();
                _this.subject.next({ action: 'viewer_loaded' });
                _this.getReport();
            });
        };
Modified Code:

Code: Select all

    ControllerService.prototype.loadViewer = function () {
        var _this = this;
        var url = this.model.requestUrl.replace('{action}', this.model.action);
        this.httpClient.post(url, this.model.createPostParameters({ action: 'AngularViewerData' }, true, false), 'json').subscribe(function (data) {
            _this.model.clear();
            var dataObject = JSON.parse(atob(data['Data']));
            var styles = dataObject['styles'];
            _this.stylesService.setupStyle(atob(styles), 'viewer');
            _this.model.options = dataObject;
            _this.checkTrExp();
            _this.initAutoUpdateCache();
            _this.subject.next({ action: 'viewer_loaded' });
            _this.getReport();
        });
    };
It looks like the expected format was a Data object base64 string for the 'styles' property. Instead I got an object where the entire Data object was a base64 string within a 'Data' property which then had a base64 string for the 'styles' property. Is there a different API source which should be used or is there an issue with the component itself?
Lech Kulikowski
Posts: 7294
Joined: Tue Mar 20, 2018 5:34 am

Re: Angular Component fails to Parse API Results

Post by Lech Kulikowski »

Hello,

Please check samples at the following links:
https://github.com/stimulsoft/Samples-JS
https://github.com/stimulsoft/Samples-Angular

Thank you.
jwcurnalia
Posts: 2
Joined: Wed Sep 23, 2020 3:40 pm

Re: Angular Component fails to Parse API Results

Post by jwcurnalia »

Sorry it took so long to respond I wanted to ensure that I was using code like what was indicated in the samples.

API:

Code: Select all

using Motivity.Reports;
using Stimulsoft.Report.Angular;
using System.Web.Mvc;

namespace Movation.Api.Controllers {
    public class PdfTestController : MovationAPIcontrollerBase {
        [HttpPost, ActionName("initviewer")]
        public ActionResult InitViewer() {
            var requestParams = StiAngularViewer.GetRequestParams();

            var options = new StiAngularViewerOptions();
            options.Actions.GetReport = "GetReport";
            options.Actions.ViewerEvent = "ViewerEvent";
            options.Appearance.ScrollbarsMode = true;

            return StiAngularViewer.ViewerDataResult(requestParams, options);
        }

        [HttpPost, ActionName("getreport")]
        public ActionResult GetReport(int id =137) {
            // retrieves a specific report (StiReport) by ID
            var report = ReportPdfHelper.GetReport(id);

            return StiAngularViewer.GetReportResult(report);
        }

        [HttpPost, ActionName("viewerevent")]
        public ActionResult ViewerEvent() {
            return StiAngularViewer.ViewerEventResult();
        }
    }
}
Component:

Code: Select all

<stimulsoft-viewer-angular
  [requestUrl]="'https://localhost/api/pdftest/137/{action}'"
  [action]="'initviewer'"
  [height]="'600px'"
>
Result:

ERROR DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

Source of Error:

Code: Select all

ControllerService.prototype.loadViewer = function () {
        var _this = this;
        var url = this.model.requestUrl.replace('{action}', this.model.action);
        this.httpClient.post(url, this.model.createPostParameters({ action: 'AngularViewerData' }, true, false), 'json').subscribe(function (data) {
            _this.model.clear();
            _this.stylesService.setupStyle(atob(data['styles']), 'viewer');
            _this.model.options = data;
            _this.checkTrExp();
            _this.initAutoUpdateCache();
            _this.subject.next({ action: 'viewer_loaded' });
            _this.getReport();
        });
    };
API Response Object:

Code: Select all

data: Object
   ContentType: "text/plain"
   Data: "eyJwYXBlclNpemVzIjpbIkxldHRlciIsIkxlZ2FsIiwiRXhlY3..."
   EnableBrowserCache: false
   FileName: null
   SaveFileDialog: false
   ShowSaveFileDialog: false
Lech Kulikowski
Posts: 7294
Joined: Tue Mar 20, 2018 5:34 am

Re: Angular Component fails to Parse API Results

Post by Lech Kulikowski »

Hello,

Please send us a sample project that reproduces the issue for analysis.

Thank you.
JussiSa
Posts: 2
Joined: Tue Aug 20, 2024 11:34 am

Re: Angular Component fails to Parse API Results

Post by JussiSa »

Hello,

I'm facing this exact same issue. Unfortunately I don't have a sample project to send since I'm working in our product code.

My InitViewer function is as below:

Code: Select all

Public Function InitViewer() As Mvc.ActionResult
    Dim oRequestParams = StiAngularViewer.GetRequestParams()
    Dim oOptions = New StiAngularViewerOptions()
    oOptions.Actions.ViewerEvent = "ViewerEvent"
    oOptions.Actions.GetReport = "GetReport"

    Return StiAngularViewer.ViewerDataResult(oRequestParams, oOptions)
End Function
My Angular component:

Code: Select all

<!-- requestUrl is generated in a property in .ts file -->
<stimulsoft-viewer-angular
    [requestUrl]="requestUrl"
    [action]="'InitViewer'"
    [height]="'100%'"
></stimulsoft-viewer-angular>
The component calls InitViewer successfully but the StiAngularViewer.ViewerDataResult() method returns an object as jwcurnalia provided earlier (sample below).

Code: Select all

{
    ContentType: "application/json"
    Data: ".........."
    EnableBrowserCache: false
    FileName: null
    SaveFileDialog: false
    ShowSaveFileDialog: false
}
The Angular component tries to parse this result and read "style" property but it is absent as is a lot more.

Why does the ViewerDataResult() return an incorrect format?

Used versions:
- Stimulsoft.Reports.Angular 2024.3.4 (NuGet)
- stimulsoft-reports-angular 2024.3.4 (NPM)
I'm in .NET Framework 4.8 environment.

Funny thing is that it works perfect on the same configuration but in project with .NET 8.0 environment.

Edit:
What should be returned (from .NET 8):
Photos_iYgX6Q3X88.png
Photos_iYgX6Q3X88.png (286.68 KiB) Viewed 13215 times
What is returned (.NET framework 4.8):
Photos_avAI9Wke9I.png
Photos_avAI9Wke9I.png (26.69 KiB) Viewed 13215 times
Vadim
Posts: 408
Joined: Tue Apr 23, 2013 11:23 am

Re: Angular Component fails to Parse API Results

Post by Vadim »

Hello

StiAngularViewer.ViewerDataResult() returns public class StiMvcActionResult : ActionResult that must exec method public override void ExecuteResult(ControllerContext context) that returns proper response
But instead of it response contains serialised object StiMvcActionResult
We can't reproduce this behaviour, maybe you have some response interceptors (or something else) that not allows to run ActionResult.ExecuteResult()
JussiSa
Posts: 2
Joined: Tue Aug 20, 2024 11:34 am

Re: Angular Component fails to Parse API Results

Post by JussiSa »

Actually found some difference: I inherit my API Controller from ApiController, not Controller like in your examples. Is there any inner workings in Controller that runs the ExecuteResult on return?

Edit: By creating a real .NET MVC route, it works as expected. So Web API ApiController cannot be used as the base.
Vadim
Posts: 408
Joined: Tue Apr 23, 2013 11:23 am

Re: Angular Component fails to Parse API Results

Post by Vadim »

Hello

You can write own wrapper for StiMvcActionResult to return necessary data for your Controller.
Post Reply