{"id":819,"date":"2018-08-07T14:46:00","date_gmt":"2018-08-07T14:46:00","guid":{"rendered":"https:\/\/staging.infragistics.com\/blogs\/?p=819"},"modified":"2025-02-26T08:25:54","modified_gmt":"2025-02-26T08:25:54","slug":"crypto-portfolio-app","status":"publish","type":"post","link":"https:\/\/www.infragistics.com\/blogs\/crypto-portfolio-app","title":{"rendered":"How to Build a Crypto Portfolio App with Ignite UI for Angular"},"content":{"rendered":"\n<p class=\"has-text-align-left\"><span style=\"font-weight: 400;\">I wanted to share with you how easy it is to create Angular application with our <a href=\"https:\/\/github.com\/IgniteUI\/igniteui-angular\" target=\"_blank\" rel=\"noopener noreferrer\">Ignite UI for Angular<\/a> <\/span><span style=\"font-weight: 400;\">toolset. <\/span><\/p>\n\n\n\n<p class=\"has-text-align-left\"><span style=\"font-weight: 400;\">What is the purpose of this application? <\/span><b>First <\/b><span style=\"font-weight: 400;\">of all, to demonstrate our Angular components. <\/span><b>Second<\/b><span style=\"font-weight: 400;\">, it\u2019s to demonstrate a real use case, and I wanted to create a system that will track my cryptocurrencies portfolio in order to check my daily gains and losses. &nbsp;<\/span><b>As for the third reason<\/b><span style=\"font-weight: 400;\">, &nbsp;to demonstrate the use of different \u0410ngular techniques like utilizing Guards, Pipes, and Custom Templates with our components and, of course, using of <\/span><b>Firebase <\/b><span style=\"font-weight: 400;\">for data storing and authentication.<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/Main.gif\" alt=\" to demonstrate the use of different \u0410ngular techniques like utilizing Guards, Pipes, and Custom Templates with our components and, of course, using of Firebase for data storing and authentication\" title=\"to demonstrate the use of different \u0410ngular techniques like utilizing Guards, Pipes, and Custom Templates with our components and, of course, using of Firebase for data storing and authentication\"\/><\/figure>\n\n\n\n<p class=\"has-text-align-left\"><span style=\"font-weight: 400;\">The topic will cover:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">The use of <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/general\/getting_started.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Ignite UI Angular CLI<\/span><\/a><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">Data services, Routing, Templating, Pipes, etc.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">The use of Firebase Data Storage, Authentication, and CRUD operations<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">Coinmarketcap API to Retrieve real-time and historical price information<\/span><\/li>\n<\/ol>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"ignite-ui-cli\">Ignite UI CLI<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">Okay, let&#8217;s start! So, have you heard about <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/general\/getting_started.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Ignite UI CLI<\/span><\/a><span style=\"font-weight: 400;\">? Yep, this is a real thing that we\u2019ve developed that helps you create Angular applications with a predefined set of components, executing just a few commands. It takes less than three minutes to install all necessary packages and to run the project with the help of our CLI, just follow our official <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/general\/getting_started.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Getting started page<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">After the building of the app is completed along with the installation of all necessary packages, you will notice that <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/navdrawer.html\"><span style=\"font-weight: 400;\">Navigation drawer<\/span><\/a><span style=\"font-weight: 400;\"> and <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/navdrawer.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Grid <\/span><\/a><span style=\"font-weight: 400;\">components were added and already configured. The same applies for the different responsive views, routing, styles, module imports, etc. &#8211; awesome, right?<\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export const routes: Routes = [\n  { path: '', redirectTo: '\/home', pathMatch: 'full' },\n  { path: 'home', component: HomeComponent },\n  ...\n];<\/pre>\n\n\n\n<p><span style=\"font-weight: 400;\">Okay, what&#8217;s next? We want our app to show variety of things: we want to have user authentication, to track crypto data changes, and to store our Cryptocurrencies portfolio somewhere. For that purpose, Ignite UI for Angular provides all suitable components out of the box. We are going to use <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/financialchart.html\"><span style=\"font-weight: 400;\">Chart <\/span><\/a><span style=\"font-weight: 400;\">for historical data changes and a <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/grid.html\"><span style=\"font-weight: 400;\">Grid <\/span><\/a><span style=\"font-weight: 400;\">to show our crypto portfolio and provide the ability to add\/update\/delete cryptocurrencies, also <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/list.html\"><span style=\"font-weight: 400;\">List <\/span><\/a><span style=\"font-weight: 400;\">and <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/card.html\"><span style=\"font-weight: 400;\">Card<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">For all of the above requirements we need to get the data from somewhere, this is where the&nbsp;<\/span><a href=\"https:\/\/min-api.cryptocompare.com\" rel=\"noopener\"><span style=\"font-weight: 400;\">min-api.cryptocompare<\/span><\/a><span style=\"font-weight: 400;\"> steps in &#8211; This is a free service that provides information for all active cryptocurrencies in one call.<\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export class BlockGridComponent implements OnInit, AfterViewInit{\n  public remoteData: CoinItem[];\n  ...\n\n  ngAfterViewInit() {\n    this.dataService.getData().subscribe(res => {\n      this.remoteData = res;\n    });\n  ...\n}<\/pre>\n\n\n\n<p><span style=\"font-size: 150%;\"><b>App Authentication\u00a0<\/b><\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">Below I\u2019ve highlighted some steps that I\u2019ve took in order to set up the Firebase authentication of the Crypto App. <\/span><b>AngularFireAuth <\/b><span style=\"font-weight: 400;\">is going to be used for user authentication and all related actions like login and logout. This firebase service provides methods for sign in with email and password, Google authentication provider, and Facebook auth provider. For a more detailed explanation, I recommend checking up the official <\/span><a href=\"https:\/\/github.com\/angular\/angularfire2\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Angular firebase repository and documentation<\/span><span style=\"font-weight: 400;\">.<\/span><\/a><\/p>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-family: inherit; font-size: inherit;\"><span style=\"font-weight: 400;\">Set up a <\/span><span style=\"font-weight: 400;\"><a href=\"https:\/\/firebase.google.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">firebase<\/a> <\/span><span style=\"font-weight: 400;\">project. <\/span><\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit; font-weight: 400;\">Go to the Authentication tab and enable Google, Facebook, and Email\/password sign-in providers.<\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit; font-weight: 400;\">Based on the methods, generate Facebook ID and later on OAuth redirect URI.<\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit; font-weight: 400;\">Add rules and publish the changes.<\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit; font-weight: 400;\">Add the firebaseConfig to the Angular project.<\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit; font-weight: 400;\">Create Login, Signup and Email components. (code for all)<\/span><\/li>\n\n\n\n<li><span style=\"font-family: inherit; font-size: inherit;\"><span style=\"font-weight: 400;\">Create auth.service that will handle the redirects of registered and unregistered users <a href=\"https:\/\/angular.io\/guide\/router#milestone-5-route-guards\" target=\"_blank\" rel=\"noopener noreferrer\">(<\/a><\/span><a href=\"https:\/\/angular.io\/guide\/router#milestone-5-route-guards\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Route guards<\/span><\/a><span style=\"font-weight: 400;\"><a href=\"https:\/\/angular.io\/guide\/router#milestone-5-route-guards\" target=\"_blank\" rel=\"noopener noreferrer\">)<\/a>. As you can see from the code, (add code), the Portfolio page is accessible only for authorized users.<\/span><\/span><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Injectable()\nexport class AuthGuard implements CanActivate {\n\n    constructor(private auth: AngularFireAuth, private router: Router, private route: ActivatedRoute) {}\n\n    canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable&lt;boolean> {\n      return Observable.from(this.auth.authState)\n        .take(1)\n        .map(state => !!state)\n        .do(authenticated => {\n          if (!authenticated) {\n            this.router.navigate([ '\/login' ], {\n              queryParams: {\n                return: routerState.url\n              }\n            });\n          }\n      });\n    }\n\n}<\/pre>\n\n\n\n<p><span style=\"font-weight: 400;\">For more details, have a look at the official firebase authentication getting started <\/span><a href=\"https:\/\/github.com\/angular\/angularfire2\/blob\/master\/docs\/auth\/getting-started.md\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">topic<\/span><\/a><span style=\"font-weight: 400;\">, and I can guarantee that you won&#8217;t feel any kind of difficulties when setting it up.<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/signin.gif\" alt=\" I can guarantee that you won't feel any kind of difficulties when setting it up.\" title=\"I can guarantee that you won't feel any kind of difficulties when setting it up.\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"data-storage-and-crud-operations\">Data Storage and CRUD Operations<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">For data storing and data updates, our application is using <\/span><a href=\"https:\/\/firebase.google.com\/docs\/database\/web\/start\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Firebase Realtime Database<\/span><\/a><span style=\"font-weight: 400;\"> which is a cloud-hosted database, stored as JSON and synchronized in realtime to every connected user. All users share on Realtime Database instance and automatically receive updates with the newest data. <\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">Reading and writing of data is easy, and below are the steps that you could follow in order to achieve CRUD operations:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">Create a separate service for data manipulations<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">Define `BlockItem` class that is going to be used for data fetch, adding, updating and removing of records.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">Create a list binding\/retrieve that will return an observable of data as a synchronized array of JSON objects. With metadata (underlying DBReference and snapshot key)<\/span><\/li>\n<\/ul>\n\n\n\n<p><span style=\"font-weight: 400;\">For more information check the official <\/span><a href=\"https:\/\/github.com\/angular\/angularfire2\/blob\/master\/docs\/firestore\/collections.md\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">firestore documentation<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">What about Grid CRUD? Yep, this is possible with the help of Firebase data storage and our great <\/span><span style=\"font-weight: 400;\">api<\/span><span style=\"font-weight: 400;\">. Check this file for more information on how to setup your Firebase platform which could provide you abilities for data storage, authentication, etc. <\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public deleteRow(cell) {\n  let blockItem = cell.row.rowData;\n\n  \/\/ Detele item from AngularFireList\n  this.deleteItem(blockItem);\n\n  \/\/ Stores deleted item for the 'Restore' Snackbar logic \n  this.deletedItem = new BlockItem()\n  Object.assign(this.deletedItem, blockItem);\n  ...\n  this.snack.show();\n}\n\npublic updateRow(evt) {\n  const rowItem = evt.rowID;\n  rowItem.holdings = evt.newValue;\n\n  this.updateItem(rowItem);\n}<\/pre>\n\n\n\n<p><span style=\"font-weight: 400;\">Full code <a href=\"https:\/\/github.com\/zdrawku\/crypto-portfolio-app\/blob\/master\/src\/app\/portfolio\/portfolio.component.ts\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"configure-all-components-that-are-going-to-be-used-in-the-application\">Configure All Components That Are Going To Be Used in the Application<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">Fetched data is used from <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/financialchart.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Charts<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/grid.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">Grids<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/list.html\" target=\"_blank\" rel=\"noopener noreferrer\">Lists<\/a> <\/span><span style=\"font-weight: 400;\">and <\/span><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/card.html\" target=\"_blank\" rel=\"noopener noreferrer\">Card<\/a> <\/span><span style=\"font-weight: 400;\">components (provide code for each). <\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">For <a href=\"https:\/\/github.com\/zdrawku\/crypto-portfolio-app\/blob\/master\/src\/app\/home\/home.component.ts\" target=\"_blank\" rel=\"noopener noreferrer\">example<\/a>, the Card component is using filtering pipes and sorting of data. <\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">export class HomeComponent implements OnInit {\n   cryptos: CoinItem[];\n   public searchValue: string;\n\n   constructor(private data: DataService, private router: Router) { }\n\n   ngOnInit() {\n      this.loadData();\n   }\n\n   private loadData() {\n      this.data.getData()\n         .subscribe(res => {\n            this.cryptos = sortDataByKey(res, 'rank');\n         });\n   }\n\n   get filterOptions() {\n      const fo = new IgxFilterOptions();\n      fo.key = 'fullName';\n      fo.inputValue = this.searchValue ? this.searchValue : '';\n      return fo;\n   }\n... <\/pre>\n\n\n\n<p><span style=\"font-weight: 400;\">Check up the code in order to see how each of the components is bound.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"grid\">Grid<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">This is the main page that is going to be used for data manipulating and tracking of price changes. We are going to define a grid with five column (count depends on the screen size) and each column will have its own ng template for data representation. This includes images, icons for price movements, and using of <\/span><a href=\"https:\/\/angular.io\/api\/common\/DecimalPipe\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">decimal pipes<\/span><span style=\"font-weight: 400;\">. <\/span><\/a><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">The action buttons above the grid will handle manual data refresh and adding of new coins. <\/span><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/dialog.html\" target=\"_blank\" rel=\"noopener noreferrer\">igxDialog<\/a> <\/span><span style=\"font-weight: 400;\">is going to be used for that purpose. A minimal validation of the coins is applied. For example, you won&#8217;t be able to add already existing coins or coins that are not present in the coinmarketcap api. Each notification message is going to be shown via <\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/snackbar.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">igxSnackBar<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">For the coin holding updates, we are going to handle (<\/span><a href=\"\/products\/ignite-ui-angular\/angular\/components\/grid.html#api\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\">onEditDone<\/span><\/a><span style=\"font-weight: 400;\">) and from there use the methods that we defined in the <\/span><b>BlockItemService<\/b><span style=\"font-weight: 400;\">. Same applied for the `<\/span><b>delete<\/b><span style=\"font-weight: 400;\">` and `<\/span><b>add<\/b><span style=\"font-weight: 400;\">` coin buttons.<\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;igx-grid #grid1 [data]=\"blockItems\" width=\"100%\" height=\"500px\" toolbarTitle=\"My portfolio\"\n   (onCellEdit)=\"updateRow($event)\" (onSelection)=\"selectCell($event)\" [showToolbar]=\"true\" \n   [columnHiding]=\"true\" [columnPinning]=\"true\">\n   ...\n   &lt;igx-column field=\"holdings\" header=\"Holdings\" editable=\"true\" sortable=\"true\">\n      &lt;ng-template igxCell let-cell=\"cell\" let-ri=\"rowIndex\" let-column=\"column\">\n         &lt;div class=\"positionTop\">\n            ${{ calculateHoldings(cell.row.rowData.holdings, cell.row.rowData.price) | number:'0.2-2' }}\n            &lt;br \/>\n            &lt;b>{{ cell.row.rowData.holdings | number:'1.0-7' }}&lt;\/b>\n         &lt;\/div>\n      &lt;\/ng-template>\n   &lt;\/igx-column>\n   ...\n   &lt;igx-column header=\"Actions\">\n      &lt;ng-template igxCell let-ri=\"rowIndex\" let-column=\"column\">\n         &lt;span igxButton=\"icon\" igxRipple (click)='deleteRow()'>\n            &lt;igx-icon>highlight_off&lt;\/igx-icon>\n         &lt;\/span>\n      &lt;\/ng-template>\n   &lt;\/igx-column>\n&lt;\/igx-grid><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"chart\">Chart<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">This component is going to be used for visual representation of the coin price changes per day. Our <\/span><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/financialchart_real_time_data.html\" target=\"_blank\" rel=\"noopener noreferrer\">igxFinancialChart<\/a> <\/span><span style=\"font-weight: 400;\">is easily configurable, as you just pass the fetched data to \u201cdataSource\u201d and, voila, everything else will be handled by the chart. Additionally, the chart respects the general financial data structure.<\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">     &lt;igx-financial-chart [dataSource]=\"data\" height=\"400px\" width=\"100%\" style=\"margin-top: 20px;\" isToolbarVisible=\"false\" chartType=\"candle\">\n      &lt;\/igx-financial-<\/pre>\n\n\n\n<p><span style=\"font-weight: 400;\">One interesting item here that should be mentioned is the use of routes to pass data between views. The Statistics page is accessible through a couple of Views which are passing different coin names to be loaded in the chart.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"list-and-card\">List and Card<\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/list.html\" target=\"_blank\" rel=\"noopener noreferrer\">IgxList<\/a> <\/span><span style=\"font-weight: 400;\">and <\/span><span style=\"font-weight: 400;\"><a href=\"\/products\/ignite-ui-angular\/angular\/components\/card.html\" target=\"_blank\" rel=\"noopener noreferrer\">IgxCard<\/a> <\/span><span style=\"font-weight: 400;\">components are used to show a different visual representation of all properties associated with the returned items.<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/static.infragistics.com\/marketing\/Blogs\/Migration\/00\/00\/00\/09\/43\/1732.2.PNG\" alt=\"IgxList and IgxCard components are used to show a different visual representation of all properties associated with the returned items.\" title=\"IgxList and IgxCard components are used to show a different visual representation of all properties associated with the returned items.\"\/><\/figure>\n\n\n\n<p><span style=\"font-weight: 400;\">To sum up, everything is possible with the right tooling, and with that said, you definitely should consider using of our <\/span><a href=\"https:\/\/github.com\/IgniteUI\/igniteui-angular\" rel=\"noopener\"><span style=\"font-weight: 400;\">Ignite UI for Angular<\/span><\/a><span style=\"font-weight: 400;\"> components for your next web\/mobile application. <\/span><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/IgniteUI\/crypto-portfolio-app\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repository<\/a><a href=\"https:\/\/github.com\/zdrawku\/crypto-portfolio-app\" target=\"_blank\" rel=\"noopener noreferrer\">&nbsp;<\/a><span style=\"font-weight: 400;\">and <a href=\"https:\/\/igniteui.github.io\/crypto-portfolio-app\/\" target=\"_blank\" rel=\"noopener noreferrer\">hosted application.<\/a><\/span><\/p>\n\n\n\n<p><a href=\"\/products\/ignite-ui-angular\/angular\/components\/general\/getting_started.html\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\"><\/span><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the next article of this series, you will learn how to implement your Firebase configuration in details.<\/p>\n","protected":false},"author":18,"featured_media":1604,"comment_status":"publish","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-819","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular"],"_links":{"self":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/819","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/comments?post=819"}],"version-history":[{"count":3,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/819\/revisions"}],"predecessor-version":[{"id":2409,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/819\/revisions\/2409"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media\/1604"}],"wp:attachment":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media?parent=819"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/categories?post=819"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/tags?post=819"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}