To continue to understand this notion of a software component, let's imagine that you want to create a page that has dynamic behaviour. For example, this page consumes data from a service available on the Web, an API that allows you to obtain the publications of an author and on the fly creates a wordcloud from the words contained in the title and summary of these publications and provides a layout of this list of publications.
Step 1: create this new component
You can always use angular cli for this.
Step 2: access angular's http service
Use angular's dependency injection mechanism to access a service to make http requests to third party services. Angular provides in its standard library a http service that can be used.
constructor(private http: HttpClient) {}
Step 3: Reuse existing component for managing a wordcloud
Since we want to generate and display wordclouds, let's search the internet to see if there is an angular component that already does this job. A quick search on the web brings us to angular-d3-cloud. Good news, such a component exists, no need to develop it, just reuse it.
Step 3.1 Install this third-party component
npm i angular-d3-cloud --save
in the module file of this new component, for example mulder.module.ts, import the AngularD3CloudModule.
Step 3.2 Use this third party component
After reading the documentation of this component, use it in the html template of the publication component.
<div id="wordcloud" class="container">
<angular-d3-cloud
[data]="data"
[width]="large"
[height]="height"
[padding]="3"
[font]="FONT"
[rotate]="0"
[autoFill]="true"
[fillMapper]="color">
</angular-d3-cloud>
Step 4. Query the API
Query the API of the publication service after having read its documentation and treat the data within the component. When initializing the component, let us do the query on the api.archives-ouvertes.fr service, then we store the data in a map indexed by year of publication (docsPerYear). We take advantage of the query result to retrieve all the terms used in the publications's abstract.
const idhal = "olivierbarais";
this.onResize({});
this.http
.get<PublicationResponse>(
"https://api.archives-ouvertes.fr/search/?omitHeader=true&wt=json&q=authIdHal_s%3A%28" +
idhal +
"%29&sort=producedDate_s%20desc&rows=2000&fl=authFullName_s,title_s,producedDateY_i,label_s,citationFull_s,keyword_s,producedDateY_i,linkExtUrl_s,fileMain_s,description_s,halId_id,language_s,publicationDateY_i,publicationDateY_s,uri_s"
)
.subscribe((r) => {
const d1: { text: any; value: number }[] = [];
this.termCount(r.response.docs)
.slice(0, this.TERM_COUNT)
.forEach((e: any) => {
d1.push({ text: e.term, value: e.count * 10 });
});
this.data = d1;
r.response.docs.forEach((d) => {
// tslint:disable-next-line:no-unused-expression
if (!this.docsPerYear.has(d.publicationDateY_i)) {
this.docsPerYear.set(d.publicationDateY_i, []);
}
this.docsPerYear.get(d.publicationDateY_i)?.push(d);
});
this.years = Array.from(this.docsPerYear.keys());
});
Step 5. Finishing the component html template for displaying the publication list
Finally, we prepare the final html template of the componen to display both the wordcloud and the list of publications.
<mulder-layout>
<mulder-main-header backgroundImage='url("assets/img/Publications-Header.jpg")' heading="Publications"
[siteHeading]="true">
</mulder-main-header>
...
<div class="container py-5 overlay">
<div id="page-content">
<div id="wordcloud" class="container">
<angular-d3-cloud
[data]="data"
[width]="large"
[height]="height"
[padding]="3"
[font]="FONT"
[rotate]="0"
[autoFill]="true"
[fillMapper]="color">
</angular-d3-cloud>
</div>
<div *ngFor="let year of years">
<h2 class="text-light bg-info py-2 px-2">{{year}}</h2>
<div *ngFor="let doc of docsPerYear.get(year)" class="publication preview-item">
<h4>{{doc.title_s}}</h4>
<h5>{{doc.label_s | author:doc.title_s}}</h5>
<h6>{{doc.label_s | descbib:doc.title_s}}</h6>
<a class="pubButton btn btn-outline-info rounded" [href]="doc.uri_s"
target="_blank">Details</a>
<a *ngIf="doc.fileMain_s" class="pubButton btn btn-outline-info rounded" [href]="doc.fileMain_s"
target="_blank">pdf</a>
</div>
</div>
</div>
</div>
</mulder-layout>
A bit of CSS ultimately makes it look better.
#research-axes {
.icon-label { margin-top: 1.5em;
h4 { font-size: 1.2em; }
}
.icon-item { margin: 20px 0; }
}
.preview-item {
margin: 20px 0;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,0.125);
border-radius: .25rem;
padding: 1em;
}
.preview-section {
margin: 30px 0;
.side-icon {
top: 10%;
}
}
Let us manage the routing to load the PublicationsComponent component of the Mulder module when someone arrive on the /publications route
The result is visible here The complete source code of this component is visible here