Skip to content

Commit a4a6fbb

Browse files
authored
Merge pull request #14 from FullStacksDev/docs-updates
Update docs
2 parents 36ebc48 + fb2180d commit a4a6fbb

File tree

6 files changed

+88
-78
lines changed

6 files changed

+88
-78
lines changed

docs/1.architecture.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ We'll dig into these in more detail in later documents.
5555

5656
> [!NOTE]
5757
>
58-
> Think of **smart components** as more involved components that have access and awareness of the broader application state and logic, via stores (and other services). They don't function just as black boxes and are not usually reusable across different parts of the app.
58+
> Think of **smart components** as more involved components that have access and awareness of the broader application state and logic, via stores and other services. They don't function just as black boxes and are not usually reusable across different parts of the app.
5959
>
6060
> Think of **presentational components** as simple and naive components that only know their inputs and outputs, making no assumptions of the overall application state and structure. They should be easy to test (as a black box) and easy to reuse.
6161
@@ -67,7 +67,7 @@ We'll dig into these in more detail in later documents.
6767
>
6868
> As a reminder, all the Angular components (including ones generated through the Angular CLI) have been configured to use the [`OnPush` change detection strategy](https://angular.dev/best-practices/skipping-subtrees#using-onpush) by default.
6969
>
70-
> This is a more performant approach that [works well with Angular's signals](https://angular.dev/guide/signals#reading-signals-in-onpush-components), and since we use NgRx SignalStore you are unlikely to hit the cases where change detection is not triggered when it should be.
70+
> This is a more performant approach that [works well with Angular's signals](https://angular.dev/guide/signals#reading-signals-in-onpush-components), and since we use NgRx SignalStore and Angular's signals to manage most application state you are unlikely to hit the cases where change detection is not triggered when it should be.
7171
>
7272
> With the caveat that forms _sometimes_ don't behave well with OnPush change detection, so in rare cases you'd need to use the `ChangeDetectorRef` to manually mark a component for change detection.
7373
>
@@ -96,7 +96,7 @@ sequenceDiagram
9696
(Ignore the time-ordering of this sequence diagram, it's just a way to visualize the data flow — it's not a strict sequence of events.)
9797

9898
- Use Angular services to wrap ALL access to databases and external services.
99-
- Use state management "stores" to encapsulate as much of the app's state and behavior as possible, leaving components to focus on UI needs and responding to state changes.
99+
- Use state management "stores" to encapsulate as much of the app's state and behavior as possible, leaving components to focus on UI needs, triggering store behaviors and responding to state changes.
100100
- Use smart components to interact with stores to bind state and trigger application logic.
101101
- Use presentational components (within the template of smart components) to abstract out UI presentation and logic in a way that does not need to know about the overall application state and structure, communicating all actions/events back to the parent smart component.
102102

docs/2.routes-and-shell.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
The base template comes with a `website` feature folder (within the `app`) where the static pages live. We could've added more pages and components here to build our logbook app, but it's better to separate it out into a dedicated feature folder ([`app/src/app/logbook/`](../app/src/app/logbook/)) and lazily load it only when the user navigates to a particular URL — `/logbook` in this case — as registered in the top-level app routes file:
88

9-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/app.routes.ts#L8-L11>
9+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/app.routes.ts#L8-L11>
1010

1111
Here, the use of an `import` for the `loadChildren` property tells Angular to separate out the code for the logbook feature into its own bundle and only load it when the user navigates to `/logbook`.
1212

@@ -16,7 +16,7 @@ Here, the use of an `import` for the `loadChildren` property tells Angular to se
1616

1717
Let's now look at the routes for the logbook feature itself:
1818

19-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/logbook/logbook.routes.ts#L9-L25>
19+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/logbook/logbook.routes.ts#L9-L25>
2020

2121
- We define a parent route that will load the `LogbookShellComponent`, with child routes defined within.
2222
- This shell component has a `<router-outlet>` in its template where a matching child route will have it's component placed in to.

docs/3.data-model-and-access.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ erDiagram
6464

6565
Given the design decision to store all entries in a single collection, we first set up the security rules to ensure proper access control:
6666

67-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/firebase/firestore.rules#L4-L19>
67+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/firebase/firestore.rules#L4-L19>
6868

6969
- This is a special "domain specific language" (DSL) that Firestore uses to define access control rules in the [`firebase/firestore.rules`](../firebase/firestore.rules) file ([docs](https://firebase.google.com/docs/firestore/security/get-started)).
7070
- `isAuthed()` and `matchesAuthedUser(userId)` are helper functions we've defined to allow easy reuse in multiple rules.
@@ -104,7 +104,7 @@ Both Angular and the Firebase JavaScript SDK have first class support for TypeSc
104104

105105
When loading entries from Firestore we want to assume they take a particular _shape_ — the `EntryDoc` type — which the TypeScript (and VS Code) tooling can then use to look for type errors and provide code completion.
106106

107-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/shared/models.ts#L15-L23>
107+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/shared/models.ts#L15-L23>
108108

109109
- This uses the `Readonly` TypeScript utility type to mark the whole object as readonly.
110110
- We build on the `WithId` type from the [`firebase/common/models.ts`](../firebase/common/models.ts) file, which adds the `id` field to the object.
@@ -122,7 +122,7 @@ When loading entries from Firestore we want to assume they take a particular _sh
122122

123123
In the same file we also define a special `NewOrUpdatedEntryInput` type for the data we send to Firestore when creating or updating an entry:
124124

125-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/shared/models.ts#L25>
125+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/shared/models.ts#L25>
126126

127127
Here we're picking a subset of the fields from the `EntryDoc` type — we only want to allow the user to set or update these fields.
128128

@@ -150,11 +150,11 @@ Let's walk through this service:
150150

151151
First, we inject the Firestore client using the helper provided from the base template:
152152

153-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/logbook/data/db/entries.service.ts#L29>
153+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/logbook/data/db/entries.service.ts#L29>
154154

155155
Next, we define a special converter object that the Firestore JavaScript library understands. We also define a reference to the collection (which we use in the actual data access methods):
156156

157-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/logbook/data/db/entries.service.ts#L31-L51>
157+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/logbook/data/db/entries.service.ts#L31-L51>
158158

159159
[Firestore converters](https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects) are a first class way to convert Firestore document data into strongly typed objects, and back. A converter is an object that conforms to the `FirestoreDataConverter` type, which requires two methods:
160160

@@ -299,13 +299,13 @@ Because Realtime Database doesn't natively support arrays we have to model the c
299299
300300
We then have some very basic security rules to allow anyone to read but no one to write (from the client-side):
301301

302-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/firebase/database.rules.json#L1-L8>
302+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/firebase/database.rules.json#L1-L8>
303303

304304
We add some tests in [`firebase/test/rtdb/rtdb-rules.spec.ts`](../firebase/test/rtdb/rtdb-rules.spec.ts) to ensure that these work as expected.
305305

306306
Finally, we have a service that wraps access to this config object (and thus the underlying categories): [`ConfigService`](../app/src/app/logbook/data/db/config.service.ts). The key line in this service is where we flatten the `categories` object into an array of strings:
307307

308-
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/f283f8f73e5d318c08d85e226a85a56f9df03d8e/app/src/app/logbook/data/db/config.service.ts#L29-L32>
308+
<https://github.com/FullStacksDev/angular-and-firebase-simple-example-app/blob/36ebc48fc9ef3f21f761ed6f60b83d2c30985fc1/app/src/app/logbook/data/db/config.service.ts#L29-L32>
309309

310310
Next we look at how we build on top of these data access services to drive state management and app logic using stores.
311311

0 commit comments

Comments
 (0)