Angular and Strapi CMS combine to offer powerful possibilities for building dynamic applications.
Together, these technologies enable the creation of scalable, secure, and maintainable applications that can seamlessly integrate content management system with sophisticated user interactions, opening up opportunities for developers and businesses alike.
In this article, we will learn how to integrate Strapi into Angular by building a News application.
In order to follow along with this tutorial, you will need the following:
npm install -g strapi@latest
).npm install -g @angular/cli@latest
)Angular, is a frontend framework, mostly used for building single-page applications. It is built and managed by Google. Angular makes it easy for developers to create functional and interactive websites that are well-structured and easy to maintain.
Strapi is a powerful headless content management system that is used to create, edit, and manage various types of content. When we say headless, we mean that, through a powerful API, it can connect to any frontend framework of your choice. Strapi supports both REST APIs and GraphQl.
By integrating Angular's frontend prowess with Strapi's backend management functionalities, developers can create web applications that not only boast visually appealing interfaces but are also easy to maintain and scale efficiently.
Now Let's understand dynamic web application by building a CRUD application using Angular for the Frontend and Strapi for the backend.
CRUD stands for Create, Read, Update, and Delete. It represents the four basic operations that can be performed on data in most database systems or web applications:
Create: This operation involves creating new records or entries in the database. In a web application context, it typically refers to adding new data to the system. For example, adding a new todo task.
Read: Reading, or retrieving, refers to fetching existing data from the database and displaying it to the user. For example, displaying a list of todo tasks.
Update: Updating involves modifying existing data in the database. This could mean changing the values of certain fields in a record or updating the entire record itself. For example,modifying the details of a todo task.
Delete: Deleting involves removing existing data from the database. It permanently removes records or entries from the system.For example, deleting a user account, removing a todo task.
Let's create a new project folder that will contain our Strapi backend. The command below creates a folder strapi-backend
.
mkdir strapi-backend
Navigate to the current directory by running the command below:
cd strapi-backend
Finally, create a new Strapi app by running the command below:
npm create strapi-app news-app --quickstart
This will create a new strapi project. The Strapi server will be started at localhost:1337
, and the URL localhost:1337/admin
will automatically be loaded in our browser by Strapi.
Fill in your details and click on the "Let's start" button. Strapi will create your account, and the admin dashboard will be displayed on your browser.
The News app will have four content types:
title
: This is the title of the newscontent
: This is the content of the newsauthor
: This is the author of the newsimageUrl
: This is the image of the newsClick "Create-Type Builder" to create a new collection type. A modal will pop up. Type "News App" in the Display name input box.
This "News App" will be the name of our collection type, and the news endpoints will be from there.
Click on the "Continue" button, a modal will appear.
This modal will be to select field for our "News App" collection. The fields in our NewsApp
model will be a "Text" field. So choose the "Text" field on the next user interface that shows. Type in "title" and click the "Add another field" button.
Repeat this process for the content
,author
, and imageUrl
fields.
After that, click the "Finish" button. The modal will disappear, and we will see the NewsApp
content types displayed with the fields that we have added. On the top right, click "Save," this will persist our NewApp collections to Strapi.
Also, see that at the sidebar that a "NewsApp" is added there alongside the "Users."
Before we test our endpoints, let's make them accessible to the public. From the left sidebar, click on Settings. Again, on the left panel under USERS & PERMISSIONS PLUGIN, click on Roles, then click on Public from the table on the right.
Scroll to the "Permissions" section and click the "Select all" checkbox. This selection will allow any user to perform CRUD operations on the news's collection. Next, scroll up and click the “Save” button as shown below.
Next, Open your project folder on your Vscode and start the server using the following commands:
npm run develop
Make sure your server is running
Let’s test our NewsApp
endpoints via Postman.
Make sure you have Postman installed. You can download it from here. If you are new to postman, you can read this documentation
We have the following news endpoints:
POST /api/news-apps
: This endpoint will be used to create a new news article. When a user sends a POST
request to this endpoint, adding the required data in the request body, a new news article is created and stored in the database.
GET /api/news-apps
: This endpoint is used to get or fetch a list of news articles. When a user makes GET request to this endpoint, it fetches a list of news articles already stored in the database.
GET /api/news-apps/:id
: This endpoint is used to get a news article by its ID. When a user makes a GET request to this endpoint, adding the particular news article ID in the URL parameter, it returns that particular news article.
PUT /api/news-apps/:id
: This endpoint is used when a user wants to update an existing news article. When a user makes a PUT
request to this endpoint adding the ID of the news article to be updated in the URL parameter and the updated data in the request body, it modifies the news article accordingly in the database.
DELETE /api/news-apps/:id
: This endpoint is used when a user wants to delete a news article. When a user makes a DELETE
request to this endpoint with the ID of the news article to be deleted in the URL parameter, it removes the news article accordingly from the database.
Follow these steps to test the Strapi API on Postman Open Postman and Create a Collection: Open Postman, and make a new collection. Name it "News App."
Add a New Request - Create News:
/api/news-apps
.POST
.Get All News:
See Data Fields: Notice that Strapi adds fields like created_at, published_at, and updated_at to hold the creation, publication, and update dates respectively.
Get News By ID:
/api/news-apps/{id}
.Edit News:
PUT
method./api/news-apps/{id}
.Delete News:
DELETE
method./api/news-apps/{id}
.For your convenience, the complete code and starter files for this project is on GitHub: https://github.com/Okeke12nancy/starter-file.
There you will find two branches, the main
and finished-project
. The latter contains the complete code and the former contains the starter code.
Clone it and install the dependencies by typing the following command on your terminal.
npm install
In this starter folder, inside the src/app
folder we will see 4 components created for you.
create-news-app
modal
news-details
news-list
There is also a news.ts
file that inside the models
folder, and a news-servie.service.ts
file inside the app
folder.We will explain what each file is responsible for as we go on.
This component handles the creation of news articles, providing a form for input and functionality to submit the data.
In the create-news-app.component.html
, paste the following code:
1<form class="form_wrapper" (ngSubmit)="onSubmit()">
2 <div class="label_input">
3 <input
4 type="text"
5 name="title"
6 id="title"
7 [(ngModel)]="newArticle.title"
8 required
9 placeholder="Title"
10 />
11 </div>
12 <div class="label_input">
13 <textarea
14 name="content"
15 id="content"
16 rows="3"
17 [(ngModel)]="newArticle.content"
18 required
19 placeholder="Content"
20 ></textarea>
21 </div>
22 <div class="label_input">
23 <input
24 type="text"
25 name="author"
26 id="author"
27 [(ngModel)]="newArticle.author"
28 required
29 placeholder="Author"
30 />
31 </div>
32 <div class="label_input">
33 <input
34 type="text"
35 name="articleImage"
36 id="articleImage"
37 [(ngModel)]="newArticle.imageUrl"
38 placeholder="Image Url"
39 />
40 </div>
41
42 @if(!isLoading) {
43 <button type="submit" class="createNews_btn">Create News</button>
44 }@else {
45 <button type="submit" disabled class="isLoading">Loading...</button>
46 }
47</form>
This HTML code above defines a form for creating a new news article. Users can enter the title, content, author, and image URL. When they click the "Create News" button, the onSubmit
function in the component class is triggered to handle form submission. The form uses data binding to keep the user input synchronized with the component's data. A button with text "Loading..." is displayed while data is submitted to prevent multiple submissions.
In the create-news-app.component.ts
, paste the following code:
1import { Component, EventEmitter, Input, Output } from '@angular/core';
2import { NewsArticle } from '../models/news';
3import { NewsServiceTsService } from '../news-service.ts.service';
4import { FormsModule } from '@angular/forms';
5import { CommonModule } from '@angular/common';
6import { RouterModule } from '@angular/router';
7import { ToastrService } from 'ngx-toastr';
8
9@Component({
10 selector: 'app-create-news-app',
11 standalone: true,
12 imports: [FormsModule, CommonModule, RouterModule],
13 templateUrl: './create-news-app.component.html',
14 styleUrl: './create-news-app.component.css',
15})
16export class CreateNewsAppComponent {
17 @Output() isModalClose = new EventEmitter <boolean>()
18 newsArticles: any = [];
19 isLoading: boolean = false;
20
21 newArticle: any = {
22 title: '',
23 content: '',
24 author: '',
25 imageUrl: '',
26 };
27
28
29 constructor(
30 private newsService: NewsServiceTsService,
31 private toastr: ToastrService
32 ) {
33 }
34
35 ngOnInit() {
36 }
37
38 isEmpty(value: string | null): boolean {
39 return value === '' || value === null;
40 }
41
42 onSubmit() {
43 if (
44 this.isEmpty(this.newArticle.title) ||
45 this.isEmpty(this.newArticle.content) ||
46 this.isEmpty(this.newArticle.author) ||
47 this.isEmpty(this.newArticle.imageUrl)
48 ) {
49 this.toastr.warning(
50 'Please fill in all required fields: Title, Content, and Author.'
51 );
52 return;
53 } else {
54 console.log(this.newArticle);
55 const article: any = {
56 title: this.newArticle.title,
57 content: this.newArticle.content,
58 author: this.newArticle.author,
59 imageUrl: this.newArticle.imageUrl,
60 };
61 this.isLoading = true;
62 this.newsArticles.push(article);
63 this.newsService.createNews({data : article}).subscribe(() => {
64 this.newArticle.title = '';
65 this.newArticle.content = '';
66 this.newArticle.author = '';
67 this.newsArticles.imageUrl = '';
68 this.isLoading = false;
69 this.closeModal()
70 });
71 this.toastr.success('Article Created');
72 }
73 }
74
75 closeModal() {
76 this.isModalClose.emit(false)
77 }
78}
This Angular component manages creating news articles. It takes user input for title, content, author, and image URL, validates that all required fields are filled, uses a news service to send the new article data to the server, shows success/warning messages using a toast service, resets the form and closes a modal after successful creation.
This component creates a modal dialog for displaying notifications to the user. It includes the structure and behavior for the modal.
In the modal.component.html
, add the following code snippet;
1<div *ngIf="isOpen" class="modal-wrapper" (click)="onClose()">
2 <div class="mode" (click)="onModalClick($event)">
3 <ng-content></ng-content>
4 </div>
5</div>
This code controls a popup window (modal). It only shows the modal when a flag (isOpen
) is true. Clicking outside the modal (on the wrapper) closes it.
In the modal.component.css
, add the following code:
1import { CommonModule } from '@angular/common';
2import { Component, EventEmitter, Input, Output } from '@angular/core';
3
4@Component({
5 selector: 'app-modal',
6 standalone: true,
7 imports: [CommonModule],
8 templateUrl: './modal.component.html',
9 styleUrls: ['./modal.component.css']
10})
11
12export class ModalComponent {
13 @Input() isOpen: boolean = false;
14 @Input() modalType: string = '';
15 @Output() isClose = new EventEmitter<boolean>()
16
17 ngOnChanges(): void {
18 this.toggleBodyOverflow(this.isOpen);
19 }
20
21 onClose(): void {
22 this.isClose.emit();
23 }
24
25 onModalClick(event: Event): void {
26 event.stopPropagation();
27 }
28
29 toggleBodyOverflow(open: boolean): void {
30 const body = document.body;
31 if (body) {
32 body.style.overflow = open ? 'hidden' : 'unset';
33 }
34 }
35}
This code defines a reusable modal component in Angular. It takes inputs for isOpen
(showing/hiding the modal) and modalType
(potentially for different modal variations). It emits an isClose
event when the modal is closed. It manages the body overflow (overflow: hidden
) when the modal is open to prevent scrolling behind it.The onClose
function triggers the isClose
event to notify the parent component about closing. The onModalClick
function prevents clicks within the modal from closing it.
Here is what the modal looks at the top-right corner of the image below.
The news-list
component will be responsible for fetching data from the Strapi backend and displaying it on the frontend.
In the news-list.component.html
, paste the following code:
1<div class="wrapper">
2 <div class="btn_wrapper">
3 <button (click)="create()" class="createNews_btn">Create News</button>
4 </div>
5 <div class="display_news">
6 @for (article of newsArticles; track article) {
7 <div class="article_card">
8 <img [src]="article.attributes.imageUrl" alt="" />
9 <div class="article_details">
10 <span class="article_title">{{ article.attributes.title }}</span>
11 <span class="article_author">By {{ article.attributes.author }}</span>
12 <button class="readMore_btn" (click)="onReadMore(article.id)">
13 Read More
14 </button>
15 </div>
16 </div>
17 }
18 </div>
19 <app-modal [isOpen]="createModalOpen" (isClose)="createModalToggle(false)">
20 <app-create-news-app (isModalClose)="closeFromCreate($event)"></app-create-news-app>
21 </app-modal>
22</div>
This code displays a news list and a "Create News" button. Clicking the button opens a modal for creating new articles. News are listed in cards with title, author, image, and "Read More" button.
The modal opens based on a flag (createModalOpen
) and closes the modal window when clicked outside or through the "Create News" component.
In the news-list.component.ts
, paste the following code
1import { Component } from '@angular/core';
2import { FormsModule, ReactiveFormsModule } from '@angular/forms';
3import { NewsArticle } from '../models/news';
4import { ModalComponent } from '../modal/modal.component';
5import { NewsServiceTsService } from '../news-service.ts.service';
6import { Router, RouterLink } from '@angular/router';
7import { CreateNewsAppComponent } from '../create-news-app/create-news-app.component';
8
9@Component({
10 selector: 'app-news-list',
11 standalone: true,
12 imports: [FormsModule, RouterLink, ModalComponent, CreateNewsAppComponent],
13 templateUrl: './news-list.component.html',
14 styleUrl: './news-list.component.css',
15})
16export class NewsListComponent {
17 newsArticles: any = [];
18 news!: any;
19 createModalOpen: boolean = false;
20
21 constructor(
22 private newsService: NewsServiceTsService,
23 private router: Router
24 ) {
25
26 }
27
28 ngOnInit() {
29 this.getNews();
30 }
31
32 onReadMore(id: any) {
33 this.router.navigate(['/articles', id]);
34 }
35
36 create() {
37 this.createModalOpen = true;
38 }
39 createModalToggle(open: boolean) {
40 this.createModalOpen = open;
41 }
42 getNews() {
43 this.newsService.getLocalState().subscribe((latestNews) => {
44 this.newsArticles = latestNews.data;
45 });
46 }
47 closeFromCreate(open: boolean) {
48 this.createModalOpen = open;
49 }
50}
This component manages a news list view. It fetches articles on startup and subscribes to updates from a news service. Clicking "Read More" on an article navigates to its detail page. The component integrates a modal window for creating new articles using separate components. It communicates with the create news component to handle modal opening/closing.
This component displays the details of a selected news article
In the news-detail.component.html
1<div class="wrapper">
2 <i class='material-icons back_icon' (click)="backToHomepage()">keyboard_backspace</i>
3 <div class="inner_wrapper">
4 <div>
5 @if (!editModalOpen){
6 <h2 class="article_title">{{ articleDetails.title }}</h2>
7
8 } @else {
9 <input
10 class="article_title_input"
11 type="text"
12 [(ngModel)]="articleDetails.title"
13 />
14 }
15 </div>
16 <div >
17 <img class="article_img" [src]="articleDetails.imageUrl" alt="" />
18 </div>
19 <!-- <div class="article_content"> -->
20 @if (!editModalOpen){
21 <div class="article_content">{{ articleDetails.content }}</div>
22
23 } @else {
24 <textarea
25 class="article_content_input"
26 [(ngModel)]="articleDetails.content"
27 name=""
28 id=""
29 cols="30"
30 rows="10"
31 ></textarea>
32 }
33 <!-- </div> -->
34 <div class="actions_btn">
35 <i
36 style="color: red; cursor: pointer"
37 (click)="deleteConfirm()"
38 class="material-icons"
39 >delete</i
40 >
41
42 @if (!editModalOpen){<i
43 style="color: blue; cursor: pointer"
44 (click)="edit()"
45 class="material-icons"
46 >edit</i
47 >} @else {<i
48 style="color: green; cursor: pointer; width: 20px"
49 (click)="editNews()"
50 class="material-icons"
51 >checkmark</i
52 >}
53 </div>
54 </div>
55 <app-modal [isOpen]="deleteModalOpen" (isClose)="deleteModalToggle(false)">
56 <div class="modal_confirm">
57 <h3>Are you sure you want to Delete Article?</h3>
58 <div class="actions_modal">
59 <button class="deleteBtn" (click)="deleteNews()">Delete</button>
60 <button class="cancelBtn" (click)="cancel()">Cancel</button>
61 </div>
62 </div>
63 </app-modal>
64</div>
This code displays an article detail view. It shows the article title and content, with an image. There's a "back" button and an "edit" button that toggles between displaying the content and editable input fields for title and content. Additionally, a "delete" icon triggers a confirmation modal asking for confirmation before deleting the article.
In the news-details.component.ts
, paste the following code:
1import { Component } from '@angular/core';
2import { ActivatedRoute, Router } from '@angular/router';
3import { NewsServiceTsService } from '../news-service.ts.service';
4import { NewsListComponent } from '../news-list/news-list.component';
5import { CreateNewsAppComponent } from '../create-news-app/create-news-app.component';
6import { ModalComponent } from '../modal/modal.component';
7import { FormsModule } from '@angular/forms';
8import { ToastrService } from 'ngx-toastr';
9
10@Component({
11 selector: 'app-news-details',
12 standalone: true,
13 imports: [
14 NewsListComponent,
15 CreateNewsAppComponent,
16 ModalComponent,
17 FormsModule,
18 ],
19 templateUrl: './news-details.component.html',
20 styleUrl: './news-details.component.css',
21})
22import { Component } from '@angular/core';
23import { ActivatedRoute, Router } from '@angular/router';
24import { NewsServiceTsService } from '../news-service.ts.service';
25import { NewsListComponent } from '../news-list/news-list.component';
26import { CreateNewsAppComponent } from '../create-news-app/create-news-app.component';
27import { ModalComponent } from '../modal/modal.component';
28import { FormsModule } from '@angular/forms';
29import { ToastrService } from 'ngx-toastr';
30
31@Component({
32 selector: 'app-news-details',
33 standalone: true,
34 imports: [
35 NewsListComponent,
36 CreateNewsAppComponent,
37 ModalComponent,
38 FormsModule,
39 ],
40 templateUrl: './news-details.component.html',
41 styleUrl: './news-details.component.css',
42})
43export class NewsDetailsComponent {
44 newsArticles: any = [];
45 deleteModalOpen: boolean = false;
46 editModalOpen: boolean = false;
47 articleId: any = '';
48 articleDetails: any = {};
49
50 constructor(
51 private newsService: NewsServiceTsService,
52 private router: Router,
53 private route: ActivatedRoute,
54 private toastr: ToastrService
55 ) {}
56
57 ngOnInit() {
58 this.route.params.subscribe((params) => {
59 const articleId = params['id'];
60 this.newsService.getNewsById(articleId).subscribe((latestNews) => {
61 this.articleDetails = latestNews.data.attributes;
62 console.log(this.articleDetails.imageUrl);
63 });
64 });
65 }
66
67 deleteNews() {
68 this.route.params.subscribe((params) => {
69 const articleId = params['id'];
70 this.newsService.deleteNews(articleId).subscribe(() => {
71 this.newsArticles = this.newsArticles.filter(
72 (news: any) => news.id !== articleId
73 );
74 this.router.navigate(['']);
75 this.toastr.success('Article Deleted');
76 });
77 });
78 }
79
80 edit() {
81 this.editModalOpen = true;
82 }
83
84 backToHomepage() {
85 this.router.navigate(['']);
86 }
87
88 editNews() {
89 this.route.params.subscribe((params) => {
90 const articleId = params['id'];
91 this.newsService.updateNews(articleId, {data:this.articleDetails}).subscribe(() => {
92 this.editModalOpen = false;
93 this.toastr.success('Article Updated ');
94 });
95 });
96 }
97
98 deleteModalToggle(open: boolean) {
99 this.deleteModalOpen = open;
100 }
101 cancel() {
102 this.deleteModalOpen = false;
103 }
104 deleteConfirm() {
105 this.deleteModalOpen = true;
106 }
107}
This component shows details for a single news article. It fetches the article by ID from the route parameters. Users can navigate back, edit the content, or delete the article. Editing updates the article and closes the edit modal. Deleting confirms with a modal before removing it from the list and navigating back.
This model represents the structure of a news item, providing type definitions for the properties of a news article.
On the news.ts
, paste the following code:
1export interface NewsArticle {
2 id?: string;
3 title: string;
4 content: string;
5 author: string;
6 imageUrl: string;
7 createdAt?: Date;
8 updatedAt?: Date;
9}
This code defines an interface named NewsArticle
. An interface is a blueprint that specifies the structure of an object in TypeScript.
This TypeScript file defines a service that interacts with an external news API to fetch news data. It provides methods for retrieving news articles and managing news-related operations.
In the news-service.ts
in the root folder, paste the following code:
1import { Injectable } from '@angular/core';
2import { HttpClient, HttpHeaders } from '@angular/common/http';
3import { BehaviorSubject, Observable, timer } from 'rxjs';
4import { NewsArticle } from '../app/models/news';
5import { switchMap, tap } from 'rxjs/operators';
6
7const httpOptions = {
8 headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
9};
10
11@Injectable({
12 providedIn: 'root',
13})
14export class NewsServiceTsService {
15 apiUrl = 'http://127.0.0.1:1337/api/news-apps';
16
17 private newsSubject = new BehaviorSubject<any>([]);
18 news$: Observable<any> = this.newsSubject.asObservable();
19
20 constructor(private http: HttpClient) {
21 this.getNews().subscribe(news => {
22 this.newsSubject.next(news);
23 });
24 }
25
26 createLocalState(news: any){
27 return this.newsSubject.next(news)
28 }
29
30 getLocalState(): Observable<any> {
31 return this.newsSubject.asObservable();
32}
33
34 createNews(news: any): Observable<NewsArticle> {
35 return this.http.post<any>('http://127.0.0.1:1337/api/news-apps', news, httpOptions);
36 }
37
38 // this is the get news that works with the endpoint
39 getNews(): Observable<any> {
40 return timer(0, 5000).pipe(
41 switchMap(() => this.http.get<any>('http://127.0.0.1:1337/api/news-apps' ))
42 );
43 }
44
45// Get a specific news article by ID
46 getNewsById(id: number): Observable<any> {
47 const url = `${this.apiUrl}/${id}`;
48
49 return this.http.get<any>(url);
50 }
51
52 // Update an existing news article
53 updateNews(id:number, news: any): Observable<NewsArticle> {
54 const url = `${this.apiUrl}/${id}`;
55 return this.http.put<any>(url, news, httpOptions);
56 }
57
58 // Delete a news article by ID
59 deleteNews(id: number): Observable<any> {
60 // const url = `${this.apiUrl}/${id}`;
61 console.log(id)
62 return this.http.delete(`${this.apiUrl}/${id}`);
63 }
64}
createNews
: Takes a news object and sends an HTTP POST request to create a new news article in the server.getNews
: Makes an HTTP GET request to the API URL to retrieve all news articles.getNewsById
: Takes an ID and fetches a specific news article using an HTTP GET request with the ID appended to the API URL.updateNews
: Takes an ID and updated news data, then sends an HTTP PUT request to update the corresponding news article on the server.deleteNews
: Takes an ID and sends an HTTP DELETE request to remove the news article with that ID from the server.This TypeScript file defines the routing configuration for the Angular application. It specifies the paths and corresponding components for different routes.
In the app.route.ts
in the root folder, paste the following code:
1import { NgModule } from '@angular/core';
2import { RouterModule, Routes } from '@angular/router';
3import { AppComponent } from './app.component';
4import { NewsListComponent } from './news-list/news-list.component';
5import { NewsDetailsComponent } from './news-details/news-details.component';
6
7export const routes: Routes = [
8 { path: '', component: NewsListComponent },
9 { path: 'articles/:id', component: NewsDetailsComponent },
10];
11
12@NgModule({
13 imports: [RouterModule.forRoot(routes)],
14 exports: [RouterModule],
15})
16export class AppRoutingModule {}
Users are directed to the NewsListComponent
when they access the application root URL: "http://localhost:4200/".
The URL pattern articles/:id
routes users to the NewsDetailsComponent
. The :id
part captures a parameter which corresponds to the ID of a specific news article. This allows routing to individual news articles based on their ID.
In the app.component.html
located in the root folder of the project directory, paste the following code:
1<router-outlet></router-outlet>
The code above is a placeholder within your application's template where components load based on routing are inserted.
This TypeScript file defines the main component of the Angular application. It serves as the root component, which is typically loaded when the application starts.
In the app.component.ts
located in the root folder of the project directory, paste the following code:
1import { RouterLink, RouterLinkActive, RouterModule, RouterOutlet } from '@angular/router';
2import { Component, OnInit } from '@angular/core';
3import { NewsServiceTsService } from './news-service.ts.service';
4import { NewsArticle } from './models/news';
5import { CreateNewsAppComponent } from './create-news-app/create-news-app.component';
6import { NewsListComponent } from './news-list/news-list.component';
7import { CommonModule } from '@angular/common';
8import { HttpClientModule } from '@angular/common/http';
9import { AppRoutingModule } from './app.routes';
10import { NewsDetailsComponent } from './news-details/news-details.component';
11
12@Component({
13 selector: 'app-root',
14 standalone: true,
15 imports: [CommonModule, RouterOutlet, CreateNewsAppComponent, NewsListComponent, NewsDetailsComponent],
16 templateUrl: './app.component.html',
17 styleUrl: './app.component.css'
18})
19export class AppComponent implements OnInit{
20 newsArticles: NewsArticle[] =[]
21 error: any;
22
23}
Here, news articles has a property newsArticles
to hold an array of news articles. error
allows storing potential errors during data fetching.
Now, we have to run our app. Type the following command on the terminal. I hope the Strapi backend is still running, if not start it up.
Before you run your application, make sure you have installed Angular CLI globally. If you haven't done that, please type the command below on your Vscode terminal:
1npm install -g @angular/cli@latest
In addition, make sure you have installed the dependencies required for the project. If you haven't done that, type the command below:
1npm install
Finally, to run the Angular server, type the command below:
ng serve --open
This will serve the Angular app at http://localhost:4200.
This is what the final application will look like:
In this article, we learnt about Angular and Strapi and how to integrate the two technologies when building a dynamic and interactive website by creating a News Application.
Integrating Strapi CMS into Angular made managing data efficient and accessible in less time. We could develop the backend quickly and get our API endpoints following best practices, saving us from the stress of building from scratch and solving bug related issues.
Full stack Developer proficient in Node JS Angular, Nest JS