Tambola — Part 3

In this article, we’ll continue with the Tambola / BINGO game development using Angular library (Angular 8).

Click here for Part 1 of the series.

Click here for Part 2 of the series.

Now that we have structure ready for the game, lets identify the models and create the same in library project.

Primarily, we have 4 entities in the game:

  1. BoardNumber
  2. Game
  3. Player
  4. Ticket

Now lets create all of the models under ‘models’ in the library via terminal window.

ng g class models/BoardNumber --project=TambolaLib --skipTests=true
ng g class models/Game --project=TambolaLib --skipTests=true
ng g class models/Player --project=TambolaLib --skipTests=true
ng g class models/Ticket --project=TambolaLib --skipTests=true

Below is the model structure:

export class BoardNumber {
value: number;
selected: boolean = false;
}
export class Ticket{
Rows: Array<Array<BoardNumber>>;
}
export class Game {
Id: number;
Name: string;
}
export class Player {
Id: number;
Name: string;
NoOfTickets: number = 1;
Tickets: Array<Ticket> = [];
}
Project Structure of Tambola Library

Now lets populate the board with the numbers. Create a service to generate the board numbers.

ng g service services/Board --project=TambolaLib --skipTests=true

Board has 9 rows with 10 BoardNumbers each. Add GenerateBoard() function tothe BoardService to generate the initial board.

board.service.ts

import { Injectable } from '@angular/core';
import { BoardNumber } from '../models/board-number';
@Injectable({
providedIn: 'root'
})
export class BoardService {
BoardData: Array<Array<BoardNumber>> = [];
constructor() { }
GenerateBoard(): Array<Array<BoardNumber>> {
this.BoardData = [];
for (let rowIndex = 0; rowIndex < 9; rowIndex++) {
let row = new Array<BoardNumber>();
for (let col = 1; col <= 10; col++) {
let bNumber = new BoardNumber();
bNumber.value = rowIndex * 10 + col;
bNumber.selected = false;
row.push(bNumber);
}
this.BoardData.push(row);
}
return this.BoardData;
}
}

Once we have the service available, we will refer the same in board component to generate the initial board in BoardComponent.

Create an instance of BoardService in BoardComponent constructor and call the GenerateBoard function to initialize the variable bound to the html.

board.component.html
board.component.ts
board.component.scss

Please refer and install, bootstrap and it’s dependencies for styling.

Now export the library components in the Library Module. Once the components are exported, these components are now available in the games application to use.

Now let’s update TambolaComponent to refer the Library components and check how it looks now.

tambola.component.html

<div class="row">
<div class="col-lg-5">
<rm-board></rm-board>
<rm-numbers></rm-numbers>
</div>
<div class="col-lg-7">
<rm-games></rm-games>
<rm-players></rm-players>
<rm-winners></rm-winners>
</div>
</div>

Now lets build the library, refer and serve the application using the script command created earlier.

npm run serve:lib
http://localhost:4200

So far we have learnt how to export components from an Angular Library. Now, let try to export a service from the library and use it in the application project.

We created a service named ‘BoardService’ in the library and used the same in BoardComponent to populate the board. You might have noticed that I intentionally kept BoardData as @Input() from the component and initialized the same in the constructor by initializing the service and calling the GenerateBoard() function of the service. Lets clean the code and remove the BoardService reference from the component.

board.component.ts

Now lets export the BoardService from the TambolaLibModule by adding the providers and using ModuleWithProviders interface.

tambola-lib.module.ts

Last thing that we have to do is to export service in the public-api.ts

export * from './lib/tambola-lib.module';
export * from './lib/services';
export * from './lib/models';

That’s it. This would export the service from the library which can be consumed in the application. Now lets see how to use this service in the application.

Lets build the library and install the same in application using below command.

npm run serve:lib

Now the service is ready to be consumed in the application. Add ‘BoardService’ as the provider in app.module.ts and implement forRoot() function on the TambolaLibModule and TambolaComponent.

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { BoardService, TambolaLibModule } from "tambola-lib";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { TambolaComponent } from "./components/tambola/tambola.component";
@NgModule({
declarations: [AppComponent, TambolaComponent],
imports: [BrowserModule,
AppRoutingModule,
TambolaLibModule.forRoot()],
providers: [BoardService],
bootstrap: [AppComponent],
})
export class AppModule {}
tambola.component.html
tambola.component.ts

Now when you run the application, output won’t change but the structure has changed completely. Library components are not completely decoupled from the service. Application is invoking the service and passing data to the components as required.

In this article, we have covered below:

  1. Identify entities and create models in the application
  2. Create service in a library project
  3. Reference angular service in a component
  4. Reference a function from the service in a component to initialize a variable
  5. Export components and service from a library
  6. Add library components and reference library service in application

Please share your comment/feedback for further improvement.

--

--