Taking advantage of cellular force, the use of a client is written in the corner.

In the article “Taking advantage of the sales force without the use of springboats”, I visited the course to introduce the springboat service which will take advantage of the well-established sales force RESTful API. The purpose of this service was to act as a middleware layer. That way, clients not listed in Salesforce can retrieve and update contact data stored in Salesforce. The backend service implemented its caching layer to provide faster response time and also reduced the number of calls to the sales force.

Taking advantage of the sales force using a client written in cellulite, I introduced a simple client written in cellulite, which made it possible to update sales force data using an online editor.

The article “Leveraging Sales Force Using a Client Written in Vue.js” introduces a client application using the Vue.js framework for further interaction with the Springboot service. Using Vue.js, the resulting client was not only able to read data from the sales force but also display the processing and display of salesforce data through the implementation of events sent from the server (SSE). Used to

The fourth article in the series, “Leveraging Sales Force Using Mobile Applications in ReactNet, once introduced local mobile applications for Android and iOS devices with a source code written in ReactNet. This new client offer allows senior executives to monitor the progress of sales force data.

In this article, we will use the Angular Framework to complete the application of a new feature. In this example, the same contact data of the sales force will be used in the drop-down list so that there is no different source of contact data.

Rethinking the use of the example.

Let’s summarize how to use your example: The Business Call Center is about to launch a major marketing campaign. However, they recently discovered that the title for the contact list was about 90% incorrect.

A team of interns is updating contacts using the Svelte client, and the management team is using the Vue.js client to monitor updates, such as events sent from the server appearing as toast messages. Are Executives are using their Android and iOS devices to monitor local clients who have been deployed.

The feature team responsible for the new widget product line has realized that they too can benefit from the contact information stored in the sales force. The following requirements have been added to the widget application.

  1. New widget form requires a contact field.

  2. The contact field selection options will be a drop-down list.

  3. The source data will be a dynamic list of contacts with the sales force.

  4. Each selection option will present the full name of the contact in parentheses with their title (if available).

  5. As the contacts in the sales force change, the list of contact selection options is automatically updated (including the title value).

The Widget Product Line feature team is planning to start this work right away and they should have everything based on the results of previous work completed for this series.

As a reference, below is a link to the SpringBoot service used for this entire series.

https://gitlab.com/johnjvester/salesforce-integration-service.

Angular is a typewriting-based web client framework led by Google and fueled by a large open source community. Of all the frameworks I’ve used in this series, Angular is definitely the largest – almost to the point where it would be better to call it a platform.

The following are some of the benefits of using Angular.

  1. Designed to handle enterprise web applications, adjusting next-generation design patterns, including progressive web applications.

  2. Evolution continues with a dedicated open source community. This leads to an impressive bug / resolution time frame and a large library of third party solutions or dependencies that can be incorporated into any modern angular project.

  3. Supported by Google, the technology serves as the primary web client framework for powerhouses including Gmail, Microsoft Office, PayPal, Upwork (freelance program), and Samsung.

Personally, I have been involved in enterprise web applications running in both Angular JS and Angular since early 2014.

For this article, I decided to step out of my comfort zone by giving version 12 of Angular. (As a reference, the last time I used version 9 for a fitness application I wrote for my brother-in-law was a series I created last year using my “brother-in-law Hiroko, a multi-tenant sauce product” series). I wrote.)

Since my Angular Command Line Interface (CLI) was still on version 9, I needed to use the following command to upgrade to version 12 of the Angular CLI.

npm install -g @angular/cli

First time users can use the same command.

To issue one ng version The command provided me with the following results:

     _                      _                 ____ _     ___
    /    _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △  | '_  / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ | | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   __| |_|__, |__,_|_|__,_|_|       ____|_____|___|
                |___/


Angular CLI: 12.2.0
Node: 14.15.5
Package Manager: npm 6.14.11
OS: darwin x64

Angular:
...

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1202.0 (cli-only)
@angular-devkit/core         12.2.0 (cli-only)
@angular-devkit/schematics   12.2.0 (cli-only)
@schematics/angular          12.2.0 (cli-only)

To create a new Angular 12 application, I issued the following Angular CLI command:

ng new salesforce-integration-angular

Angular CLI has created an application in a new folder called Sales Force Integration Angular. Below is a summary of some command output:

? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? CSS
...
✔ Packages installed successfully.

At this point, I used the `ng serve` command to show the newly created angular application:

Sure, there isn’t much, but at least the angular application started in seconds.

Adding some dependencies.

There is an interesting business principle in the needs of the widget application. To avoid scrolling back to the top of the page, I captured the information below:

As the contacts in the sales force change, the list of contact selection options is automatically updated (including the title value).

This requirement translates into the widget application to maintain the status quo of the contact items. Meaning, contact list information always needs to be present.

In the article “Taking advantage of the sales force using a client written in Vue.js”, the Springboot service was updated to broadcast to SSE as changes were made to the status of contacts stored in the sales force. ۔ The angular application will also need to listen to the same SSE.

However, with the Angular application, I decided to use use ngrx / store, which is a redox-inspired global estate management for Angular applications powered by RxJS. This means that I will wire the SSE from the springboot to maintain the status of sales force contacts within the browser. After that, the widget component can always use responsive design to make the latest changes – without calling the SpringBoot service any more.

A simple command is required to add NGRX / Store dependencies to the Angular 12 application.

npm install @ngrx/store --save

With the inclusion of this single dependency in the project, I can focus on creating a widget component in Angular.

Widget component creation

For this simple example, launching the Angular 12 application will introduce a new widget form. Since we’re keeping things simple, the form will look like this:

The model field will be a freeform text field and the contact field will contain a dynamic list of Sales Force contacts, the latest through SSE listeners interacting with NGRX.

The following command is required to create a new component using the Angular CLI.

ng generate component widget

The Angular CLI responds with the following status updates:

CREATE src/app/widget/widget.component.css (0 bytes)
CREATE src/app/widget/widget.component.html (21 bytes)
CREATE src/app/widget/widget.component.spec.ts (626 bytes)
CREATE src/app/widget/widget.component.ts (275 bytes)
UPDATE src/app/app.module.ts (727 bytes)

As a result, a widget component has been created and is ready for use in the ular / src / app / widget` folder of the Angular 12 application.

Configuration of NgRx

Instead of including all the necessary information about configuring NgRx here, the following link to the NgRx website provides much more detail.

https://ngrx.io/guide/store#ngrxstore

This documentation section includes the following outline:

At a higher level, we will add the following elements to the Angular 12 application:

  1. Contact Service: To make API calls on SpringBoat, allows us to receive contacts.

  2. Event Service: Liaison with SSURI running Spring Boat Service.

  3. Contact Effect: To register event listeners and load actual contacts from the Spring Boat service.

  4. Contact Action: Explain incidents sent from the contact service.

  5. Contact Reducer: To ensure implementation of state changes.

  6. Contact selector: To select and obtain contact information from the store.

  7. WidgetComponent: To listen to the contact action and retrieve data from the contact selector.

Let’s dive into the code and see what it looks like in TypeScript.

Convenience

The contact service manages the SpringBoot service to make basic API calls that have been used in this regard. The Angle 12 client will make only one call. /contacts Return the URI and a “viewable” list of contact items:

export class ContactService {
  constructor(private http: HttpClient) { }

  getContacts(): Observable<Contact[]> {
    return this.http.get<Contact[]>( environment.api + '/contacts')
      .pipe(
        retry(1),
        catchError(this.handleError)
      )
  }
}

Event service

The event service establishes a connection to the URI in the springboat that is broadcasting the SSE updates. I added getServerSentEvent() How to make connection:

getServerSentEvent(): Observable<any> {
    return Observable.create((observer: { next: (arg0: any) => void; error: (arg0: any) => void; }) => {
      const eventSource = this.setSource();
      eventSource.onmessage = event => {
        this.zone.run(() => {
          observer.next(event);
        });
      };
      eventSource.onerror = error => {
        this.zone.run(() => {
          observer.error(error);
        });
      };
    });
  }

When an SSE arrives, _onMessage() The method is called:

private _onMessage(e: MessageEvent): void {
    const message = JSON.parse(e.data);
    if (message) {
      this.dispatchActionInNgZone(processSseUpdate(message));
    }
  }

As a result this process sends to NgZone:

private dispatchActionInNgZone(action: Action): void {
    this.zone.run(() => this.store.dispatch(action));
  }

Contact effect.

The Contact Effects event service registers the event listener, updates the contacts from the SSE messages that are received, and loads the actual contacts from the Springboot service.

registerEventListener$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(ContactActionTypes.AllContactsLoaded),
        tap(action => {
          this.eventListenerService.register();
        }),
        repeat()
      ),
    { dispatch: false }
  );

  updateContactFromSSE$ = createEffect(() =>
    this.actions$.pipe(
      ofType(processSseUpdate),
      map( payload => {
        const anyContact:any = (payload as any);
        const contact = (anyContact as Contact);
        const updatedAction:Update<Contact> = {
          id: contact.id,
          changes: { ...contact }
        };
        return new ContactUpdated({contact: updatedAction});
      })
    )
  );

  loadAllContacts$ = this.actions$.pipe(
      ofType<AllContactsRequested>(ContactActionTypes.AllContactsRequested),
      mergeMap(() => this.contactService.getContacts()),
      map(contacts => { new AllContactsLoaded({ contacts })} )
    );

Contact Action.

Contact action describes events that are sent from the contact service.

export enum ContactActionTypes {
  AllContactsRequested = '[Contact API] All Contacts Requested',
  AllContactsLoaded = '[Contact API] All Contacts Loaded',
  ContactUpdated = '[Contact API] Contact Updated'
}

export class AllContactsRequested implements Action {
  readonly type = ContactActionTypes.AllContactsRequested;
}

export class AllContactsLoaded implements Action {
  readonly type = ContactActionTypes.AllContactsLoaded;
  constructor(public payload: { contacts: Contact[] }) { }
}

export class ContactUpdated implements Action {
  readonly type = ContactActionTypes.ContactUpdated;
  constructor(public payload: { contact: Update<Contact> }) { }
}

export type ContactActions = AllContactsRequested |  AllContactsLoaded | ContactUpdated;

Contact the reducer.

The contact reducer ensures that state changes are implemented.

export function contactReducer(state = initialContactsState, action: ContactActions): ContactsState {
  switch(action.type) {
    case ContactActionTypes.AllContactsLoaded:
      return adapter.setAll(action.payload.contacts, {...state, allContactsLoaded: true });
    case ContactActionTypes.ContactUpdated:
      return adapter.updateOne(action.payload.contact, state);
    default: {
      return state;
    }
  }
}

WidgetComponent

Finally, WidgetComponent utilizes all NgRx state administrative elements to provide a dynamic and self-updating list of contact information to the sales force via the SpringBot service and SSE URI.

Of ngOnInit() Method connects to the NgRx store, then receives the original list of contacts:

ngOnInit(): void {
    this.widget.model = "Some Model Description Goes Here";

    this.contactService.getContacts().subscribe((data) => {
      this.store.dispatch(new AllContactsLoaded({ contacts: data }));
      this.loading = false;
    });
  }

With the implementation of NgRx, updates will be processed as they are received from the SpringBoot service over the SSE URI.

To make sure the widget component appears when Angular starts, I reduced the app.component.html file to one line:

<widget></widget>

Use of angular application.

Using ng serve With the Angular CLI, we’ve started the Angular 12 application with all of the above changes.

Displays this widget form, displays sales force contact data in the drop-down list:

Using the following cURL command, I updated the title of Rose Gonzalez from “SVP, Purchase” to “SVP, Information Technology”.

curl --location --request PATCH 'http://localhost:9999/contacts/0035e000008eXq0AAE' 
--header 'Content-Type: application/json' 
--data-raw '{
    "Title": "SVP, Information Technology"
}'

The PATCH command resulted in HTTP status code 202 (accepted) and returned the following payload:

{
    "attributes": {
        "type": "Contact",
        "url": "/services/data/v52.0/sobjects/Contact/0035e000008eXq0AAE"
    },
    "id": "0035e000008eXq0AAE",
    "Name": "Rose Gonzalez",
    "Title": "SVP, Information Technology",
    "Department": "Procurement"
}

Without making any changes to the widget form, the drop-down list options now appear as follows:

Notice how the contact title for Rose Gonzalez changed automatically.

Result

Starting in 2021, I am trying to live up to the following mission statement, which I think can be applied to any IT professional.

“Focus your time on providing features / functions that enhance the value of your intellectual property. Take advantage of frameworks, products and services for everything.

– Jay Wester

In this article, I created a widget component using Angular 12 that includes a drop-down list of contacts with data from within the sales force implementation. I added the NgRx state management functionality to listen to SSE messages from SpringBot so that the contact list can be maintained. In this case, I took advantage of the powerful NgRx State Management Framework to make it work for me – requiring very few changes to the widget component.

Like my experiments with Svelte, Vue.js, and React Native, the time to create a ready-to-deploy component was very fast, measured in minutes instead of hours. Just like in all the articles in this series, we have been able to use sales force without any sales force client.

Of course, the production-ready scenario will require some additional work to prepare this application for “prime time” use.

If you are interested in the source code used for Angular Client, visit the following repository on GitLab.

https://gitlab.com/johnjvester/salesforce-integration-angular

In the next article in this series, I plan to turn things 180 degrees and use Lighting Web Components (LWC) outside of the sales force ecosystem.

Have a really great day!

.

Write a Comment

Your email address will not be published. Required fields are marked *