Loading data before rendering a component in Angular2 and AWS Lambda: Best practices

Currently, I am utilizing a Lambda function to retrieve data from a database and would like to ensure that the page rendering process is delayed until the data has been fetched.

I am aware that there is a way to achieve this using a combination of promises and *ngIf, as explained here. However, I am unsure of how to integrate this solution into my existing code.

Here is a snippet of my code:

overview.component.ts

export class OverviewComponent implements OnInit {
  businessPartner: any;
  bpNumber: number;
  paymentDetail: PaymentDetails;
  response: any;

  constructor() { }

  ngOnInit() {
        AWS.config.update({
            //Testuser
            accessKeyId: "XXXXXXXXXXXXX",
            secretAccessKey: "XXXXXXXXXXXXXXXXXX",
            region: "eu-west-1",
        });

        //get bpNumber from session storage
        this.bpNumber = +JSON.parse(sessionStorage.getItem('bpNumber'));

        this.lambdaGetBp(this.bpNumber);

        };


  lambdaGetBp(bpNumber: number): any{
      var lambda = new AWS.Lambda();
        var params = {
        FunctionName: 'readFromDynamoDb', /* required */
            Payload: JSON.stringify({ 
                bpNumber : bpNumber,
            })
        };
       lambda.invoke(params, function(err, data) {
            if (err) console.log(err, err.stack);    // an error occurred
            else {
                var jsonObj = JSON.parse(data.Payload)
                console.log(jsonObj)           // successful response
                return jsonObj;
            }    
        });
  }

  click(){
      console.log(this.businessPartner);
  }


}

And here's my Lambda function in index.js

'use strict';

var AWS = require('aws-sdk');

var docClient = new AWS.DynamoDB.DocumentClient({ region: 'eu-west-1' });


exports.handler = function(e, ctx, callback) {
    let table = "dsbTable";
    let bpNumber = e.bpNumber;
    let params = {       
        TableName: table,
        Key: {
            "bpNumber": bpNumber
        },
    };
    docClient.get(params, function(err, data) {
        if (err) {
            console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
            callback(err, null);
        } else {
            var xml2js = require('xml2js'); // XML2JS Module
            var parser = new xml2js.Parser(); 

            parser.parseString(data.Item.getBp, function(err, result) {
                if (err) {
                    console.log('Error!!!!!!')
                } else {
                    data = result;
                    console.log('Done');
                }

            });
        };
        callback(null, data);

    });

};

Your assistance with this matter is greatly appreciated :)

Answer №1

Finally, the solution clicked and it turned out to be surprisingly simple. All that was needed was to encapsulate the lambdaGetBp() method in a Promise or rather wrap the code inside it with one.

The revised code snippet is as follows:

  lambdaGetBp(bpNumber: number){
      return new Promise((resolve, reject) => {          //HERE
        var lambda = new AWS.Lambda();
            var params = {
                FunctionName: 'readFromDynamoDb', /* required */
                Payload: JSON.stringify({ 
                    bpNumber : bpNumber
                })
            };
        lambda.invoke(params, function(err, data) {
                if (err) console.log(err, err.stack);    // an error occurred
                else {
                    var jsonObj = JSON.parse(data.Payload);
                    console.log(jsonObj);           // successful response
                    resolve(jsonObj);                    // AND HERE
                }    
            });
        });
  }

Following this, simply call it as a regular promise within the ngOnInit() function.

this.lambdaGetBp(this.bpNumber).then(data => this.bp= data);

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

Utilizing event listeners with image elements in React for interactive typing experience

When I attempt to type the event as React.ChangeEvent<HTMLImageElement> in order to make the e.target.src work, I encounter the following error messages in the imageFound and ImageNotFound functions: Type '(evt: React.ChangeEvent) => void&a ...

Tips for extracting data from an Angular object using the *ngFor directive

https://i.stack.imgur.com/ai7g1.png The JSON structure displayed in the image above is what I am working with. My goal is to extract the value associated with the key name. This is the approach I have taken so far: <span *ngFor="let outlet of pr ...

Issue with Constructor: The type 'void' cannot be assigned to type 'any[]'

I'm a novice when it comes to Angular. Please excuse any errors I make as I am still learning. I currently have a DataService called WatsonService and a component that needs to process data retrieved from the IBM Watson Cloud using BearerAuthenticato ...

What is the relationship between directives, templates, and ViewContainers in Angular?

I have implemented a basic functionality in my component where numbers are injected after a delay using a custom directive called *appDelay It is known that the Angular syntax hints with * will de-sugar into something like this: <ng-template ...> .. ...

Client-side condition handling in Angular 2

How can I change the icon image on a block/unblock button based on the user's active status? For example, showing an unlock image when the user is active and vice versa. Image https://i.stack.imgur.com/aM0ff.png Html <link href="../../font-aw ...

What is the best way to integrate model classes within an Angular module?

I have a few classes that I want to keep as plain bean/DTO classes. They are not meant to be display @component classes, @Pipe classes, or @Directive classes (at least, that's what I believe!). I am trying to bundle them into a module so that they ca ...

Troubleshooting CSS Issues in ASP.NET Boilerplate

I am attempting to apply a CSS style to a text input similar to the one found on the CreateUser default page. However, I am encountering an issue where the blue line under the textbox does not appear when I navigate away from and then return to the page. ...

Using Angular2 to implement a 'pattern' for form builder functionality

Currently, I have a form builder pattern in my project and it looks like this: this.userForm = this.formBuilder.group({ 'postalCode': ['', Validators.pattern('/[A-Za-z][0-9][A-Za-z] [0-9][A-Za-z][0-9]/i')] }); In ...

Encountering a problem with Webpack SASS build where all files compile successfully, only to be followed by a JavaScript

Being a newcomer to webpack, I am currently using it to package an Angular 2 web application. However, I am encountering errors related to SASS compilation and the ExtractTextPlugin while working on my project. Here is a snippet from my webpack configurat ...

"Angluar4 is throwing an error: it's unable to read the property 'iname' of

This is the code snippet from item.ts file:- export interface item{ $key?:string; available?:boolean; countable?:boolean; iname?:string; price?:string; desc?:string; image?:string; } The items component item.componenet.ts looks like this:- import { Com ...

Using a dynamic variable to access an Angular getter within a template expression

Imagine having an Angular (6+) component structured like this example: @Component({ selector: 'my-component', template: '{{test}}' }) export class MyComponent { test = 'myData'; co ...

What is the process of attaching a property to every object within an array using TypeScript?

In my search for adding a property to each object in an array, I came across a solution in AngularJs on Stack Overflow. However, I attempted the following approach which did not yield the desired outcome. Any assistance would be greatly appreciated. ex ...

Dealing with Errors in Angular 2/4 using forkJoin for Multiple URLs

I am currently using Angular 2 and implementing forkJoin for a particular scenario where I need to make multiple REST calls in parallel. Below is the function I am using: private getBatchObservableData(data: Array<Widget>): Observable<any> { ...

Angular 5 Tutorial: Defining the "of" Method in HTTP Services

Currently, I'm studying the Angular 5 HTTP tutorial. Everything was going smoothly until I encountered a strange issue in my Ionic project where it started throwing an error stating that "of is not defined". /** * Handle Http operation that failed. * ...

Precise object mapping with Redux and Typescript

In my redux slice, I have defined a MyState interface with the following structure: interface MyState { key1: string, key2: boolean, key3: number, } There is an action named set which has this implementation: set: (state: MyState, action: PayloadAct ...

Creating an interface that extends the Map object in TypeScript to maintain the order of keys

After learning that the normal object doesn't preserve key order in TypeScript, I was advised to use Map. Nevertheless, I'm struggling to figure out how to assign values once I've declared the interface. Take a look at my approach: Coding ...

Highcharts 7 - Positioning an Annotation in the Center

I would like to display an annotation above specific data points on my Highchart. Currently, the annotation appears at the location of the data, but it is not centered directly over the point. I want the annotation to be perfectly centered on the data poin ...

Tips for transferring observable to parent component in angular 2?

I have two components, SearchComponent and RuleListComponent. The Search component is a child of RuleList. https://i.stack.imgur.com/rFlM2.png I need the SearchComponent to retrieve data using APIService. This data should then be passed to RuleList as an ...

Unable to send JSON data from server to client following a successful file upload operation

I'm currently working on a project that involves NodeJS, Express, JQuery, and Typescript. The issue I'm facing is related to uploading a file from the front end, which is successful. However, I'm encountering difficulties in returning a JSON ...

Add vue-loader to an AngularJS project

I currently have a rails/angular application, and I am considering transitioning to vue. In order to make this migration successful, I will need to begin loading .vue files in my app using vue-loader. import vueComponent from './myVueComponent.vue&ap ...