Download the GitHub repo.Check out the demo.
Imagine we need an app to run a parking lot with not too many requirements — parking slots should be cleaned and maintained. Spots will be rented or owned and customers will need to pay for the service. All of this data, along with customer information, will need to be stored for easy access. In this article I’ll show you how to create this basic data management app using Cosmic JS.
First, register in Cosmic JS and create your own bucket.
After that we need to create a couple of Object Types: one for describing a parking spot, and another one for an event, happened to the spot. It might be one of three different types: payment, maintenance or cleaning.
To do it, within your bucket click “Add Object Type”
Every Object has built-in properties like title, slug, and content. Usually, it’s quite enough, but let’s make our Object Types more specific. Metafields to the rescue!
Add a list to keep a floor number and fill it with values ‘Ground’, ‘First’ and ‘Second’.
After that create another Object Type, spot event. Add Metafield type (‘Payment’, ‘Maintenance’ and ‘Cleaning’) and event date (as date typed Metafield). Don’t forget to add one more field with type ‘Object’ to point a parent spot.
Now we need to add a tiny scent of security: set up write_key and read_key to restrict anonymous access to our data.
They are controlled by Settings -> Basic Settings page
Ok, our backend is complete. Our app will use powerful Cosmic JS API to operate, and all we need is to write a single page application. Angular 2 is a good solution for this.
First, we need to install NodeJS and its package manager NPM (surprisingly, it stays for NodeJS Package Manager). Here is quite a useful link: https://nodejs.org/en/download/package-manager/
Install Angular CLI (command-line interface). Take it from here: https://angular.io/guide/quickstart
Also, check out the code here: https://github.com/cosmicjs/parkingcare2/
and view demo app here: https://parkingcare.cosmicapp.co/
Now open a console/command line/whatever you have to run commands and create a folder, get into it and type
ng new ParkingCare. Ok, we have a sample project installed.
All the people were excited by Bootstrap years ago, so now it’s everywhere and looks boring. Take fresh and crisp Bulma framework. You can read about it here: https://bulma.io/
Another great UI thing is Font Awesome. Check it out here, if you haven’t done yet: https://fontawesome.com/
Go to parkingcare/src/index.html and add references for Bulma and Font Awesome
Let’s see how it looks now: run ng serve — open
Within app, folder create another three: models, services, and components
Create data models for our app: get into /models and type ng generate class entity, ng generate class spot, ng generate class spotevent. As TypeScript support inheritance everything common into an entity class and keep specific data in derived classes: Spot and SpotEvent
Create another class called Settings and post this data into it. This data will serve as application configuration file
Now we need to create a service — that exact thing which will pump API-calls for us. Move to the /services folder and type ng g service data (“g” means “generate”). We fill it a bit later.
Now move to the /components and create a few components:
Dashboard (ng g component dashboard) — for the main page
Spotcard (ng g c dashboard) — for particular spot page
Spotcardedit (ng g c spotcardedit) — spot edit form
Eventcardedit (ng g c eventcardedit) — spotevent edit form
Now we need to add a router to explain to the system which component should be used for exact URL. Nice explanation located here https://angular.io/tutorial/toh-pt5
There are few request types we need to serve:
In the app/app-routing.module we need to assign components to the paths.
Ok, we created a routing, let’s see how it looks. Run ng serve — open again. See no changes. It is because we need to add a router-outlet tag to the app.component.html.
Adjust it and run ng serve — open. Now it works.
It’s time to make some UI. Our entry point, the dashboard, will show user two blocks:
Go to the app/componens/dashboard/dashboard.component.html, create there a two-columns layout (let’s give two-thirds to the overview) and put component tags: app-spotlist and app-eventlist. But component tags won’t work without a data. Let’s pass some Objects there, “spots” for spot list and “spotEvents” for last events.
These Objects are described in dashboard.component.ts. We need to go deeper there.
Go to the /services/data.service.ts and create a few functions there:
Some of them will be used for getting data, some of them for changing data.
Starting with a simple one: getting spot list. We will use RxJS (http://reactivex.io/rxjs/)
First, compose a proper URL to call Cosmic JS API.
After that call API by GET method and return thing, called Observable
Make similar to the event list.
And make final function getSpots()
return Observable.forkJoin(this.getSpotData(), this.getSpotEvents());
It will return all data when both lists ready.
Enough here, let’s go back to the dashboard.component.ts
Within ngOnInit we subscribe to the service function, and when receive a data we do some data transformation: repack received data into our Objects “spots” and “spotEvents”, which were described previously.
As our Objects inflated, they should be rendered on the page. We need to add couple more components: spotlist and eventlist (ng g component spotlist, ng g component eventlist)
In the component’s .ts file set @Input as an Object list (to be able to pass it to the component),
In .html file describe the list using *ngFor=”let spot of spots” to iterate Objects within the passed list.
For the event list, it is quite similar.
Our actions like adding or moving to the display page present as a link, but with routerLinkparam instead of href.
Also, there are some button click handlers. They are set up in (click)=”func(param)” way.
To create an Object we need to send a properly-formed json to the Cosmic JS API with a write key, passed in the payload. Let’s go to the services/data.service.ts and create a function for serving new spot creation.
By default, it is required to pass a title and type_slug. As we have a more complex Object, we also need to pass a metadata and write_key in out payload Object.
Don’t forget to add a header Content-Type: application/json. API won’t be able to recognize a payload without it. Send it with a POST to the /add-object and get a new Object back. It is pretty obvious.
To change your Object you need to POST another json to the Cosmic JS API “edit-object” controller. In that json you need to pass a write_key, updated Object slug, title, content and all Metafields (event if they not changed). And, of course, don’t forget Content-Type header.
As all out inner Objects are children of common Entity type we can use a common function because the only thing Cosmic JS needed to remove an Object — it is its slug. You have to call DELETE request to the API’s “objects” controller. In our case, we also need to pass a write_key, so here is a trick: we add a json {“write_key”: “”} as “body” option to the request. And it works just well.
Before removing a spot we need to ensure that bound events do not exist. So we call a function which checks that no events are bound to the spot. We can show the warning if the spot cannot be deleted. *ngIf is used for it
In components/spotcard/spotcard.component.html
And in components/spotcard/spotcard.component.ts
Well, now we need to deploy this somehow. Cosmic JS provides a nice and quite easy way to launch your app, PaaS based on Dokku. You just go to the Settings -> Deploy Web App in the left menu, fill the repo URL and click the blue button which says “Deploy to Web”.
Well, as we have an angular application, some extra preparations are required.
To make entire picture clear, we need to understand following statements:
Ok, let’s adjust the package.json a bit.
Here is the code of server.js
and part of the package.json
After these preparations commit everything to the repository, go to the deployment page (once again, Settings -> Deploy Web App) and click “Deploy to Web”. In a while, you receive an email from Cosmic JS as a successful deployment confirmation. If no, you can check that page again for the error log, if any.
Now, when you see how simple and cozy it is, I hope you are excited enough to bring your ideas to life with Angular and Cosmic JS.
This article originally appeared on Cosmic JS.