This is the most common approach that I’ve seen being used. We start by creating a new component for Address.
1
|
|
We move over the html and typescript code for rendering Address into its component. Since we need access to the root FormGroup, we pass it via an @Input
. In the ngOnInit()
method for the Address component, we can add the Address controls to the parent formgroup.
To read the dirty/valid status of the Address component in the parent control, we can try and get the child control via something like profileForm.get('address')
and then read the corresponding properties. But this goes against the principle of encapsulation, as we’ll be relying on knowing the internal implementation of a Component. A better way would be to expose the needed properties on the Address component and accessing them from the parent, so I’ve added isValid
and isDirty
getter properties. You can review the code/demo below.
Pros:
Cons:
From the documentation on ControlContainer, it is:
A base class for directives that contain multiple registered instances of NgControl. Only used by the forms module.
This approach is similar to the previous one, but instead of passing the parent FormGroup via an @Input
, we inject the ControlContainer
class into the constructor of our Address component. This gives us access to the parent FormGroupDirective and lets us get to the corresponding control. Other than that, the solution is pretty similar to Approach 1 above, and you still have to create additional properties on the Address component to track the dirty/valid status.
Pros:
Cons:
To learn more about using this approach, you can watch Jennifer Wadella’s talk from ng-conf.
From the documentation, ControlValueAccessor
Defines an interface that acts as a bridge between the Angular forms API and a native element in the DOM.
To be more closely aligned with Angular Forms, we’re going to implement the ControlValueAccessor interface on our Address Component. This means we’re going to implement the following 4 methods.
1 2 3 4 5 6 |
|
Let’s look at each of these:
writeValue()
is called by the forms API to write to the view when programmatic changes from model to view are requested. We can do this by using the setValue() (or patchValue(), depending on the data you’re getting) method in the forms API.registerOnChange()
registers a callback function that is called when the control’s value changes in the UI. With forms API, we can find out when the control value changes by subscribing to valueChanges observable on our component’s FormGroup.registerOnTouched()
registers a callback function that is called by the forms API on initialization to update the form model on blur. We don’t care about the touched status in this sample, so we can leave it blank.setDisabledState()
is called by the forms API when the control status changes to or from ‘DISABLED’. We can enable/disable our FormGroup as needed. After implementing ControlValueAccessor interface methods, we need to register a NG_VALUE_ACCESSOR
provider.
1 2 3 4 5 6 7 8 |
|
If you want to learn more about ControlValueAccessor, this post explains it in depth.
Now we still need to expose the validity status of the component. To do so, we need to implement the Validator
interface, and then register it a NG_VALIDATORS
provider, like we did for NG_VALUE_ACCESSOR. I learned about this approach from this post. Since our Address component is behaving like an Angular Forms Control, we can read the valid and dirty status in the parent html just like how we do it with Angular Forms (profileForm.get('address').valid
and profileForm.get('address').dirty
)
The final source code and demo is below:
Pros:
Cons:
Kara Erickson covered ControlValueAccessor in her Angular Forms talk at Angular Connect (Nested forms starts at 25:23).
We looked at 3 different alternatives for implementing Nested Forms in Angular in this post. They might all be good solutions, depending on your requirements, but it might not be a bad idea for you and your team to be on the same page regarding your available options, and preferred solutions, on a project.
The code for all the 3 approaches can be seen in the github repo. There’s a branch corresponding to each approach.
]]>To create a simple example, I am going to use the final code from the Tour of Heroes tutorial as my starting point. I’ll focus on ‘HeroDetailComponent’ for this post. The initial template and the corresponding component typescript code is below:
This is currently a mixed component, since we are dealing with services like the HeroService, as well as defining the look and feel of the Hero Detail Component. We can split it up into 2 components, a Container component that contains all the business logic, and a Presentational Component that will live inside the Container component, and define the UI.
Let’s start with the Presentational component. We already have an @Input for the hero to bind to. Let’s add 2 @Outputs corresponding to the click of the “go back” and the “save” buttons, and emit events when those buttons are clicked. The code for the template and the component should look like:
Next we can create the Container component. The template will just interact with the Presentation component we defined above, and pass it the data it needs, as well as handle the events raised by it. In the component code, we can initialize the hero in the constructor, and add event handlers for saving the details, and going back to the previous screen. The code is below:
Note: To get the app to work again, you will have to register the new Container Component in the app module, and also update the route file (app-routing.module.ts) to point to the Container Component instead of the old one.
Container component templates have no logic in them to test. Therefore, we can bypass the whole Angular TestBed setup. Since Angular compiles components for every test case, we are skipping compilation, DI and component lifecycles. This results in simpler and faster unit tests. I have created some sample unit tests for our new container component.
The code shown in this post can be accessed here. Some of the advantages of taking this approach are:
This article explains it better.Use the CheckOnce strategy, meaning that automatic change detection is deactivated until reactivated by setting the strategy to Default (CheckAlways). Change detection can still be explicitly invoked.
With the default strategy, any change (user events, timers, XHR, promises, etc.,) triggers a change detection on all components. With OnPush strategy, the component only depends on its @inputs(), and needs to be checked if
- the Input reference changes
- A DOM event originated from the component or one of its children.
- Change Detection is run explicitly.
I hope you found this useful. If you would like to explore the ideas expressed in this post further, Lars Gyrup Brink Nielsen wrote a bunch of articles where he takes this concept to the next level and implements the MVP pattern in Angular.
]]>Mommy's working today, so it's dad son time at the library. pic.twitter.com/atA6ys1m7s
— Latish (@Latish) September 8, 2018
I hope you all had a great year as well, and have a wonderful 2019.
]]>One question I get regularly is about my note taking process. I use a Livescribe Echo pen to take notes in a notebook as I am reading. I later run the notes through an OCR plugin. The output text has anywhere from 70-90% accuracy, which I then fix by hand. I used netlify to host the site, and it has been a wonderful experience so far.
Going forward, I’ll post my future notes on the new site. Happy book reading!
]]>The biggest change was our son Dev being born in June.
I am now a dad! Dev Sehgal was born on Friday. Both Mom and Baby are doing well. pic.twitter.com/ss1ytqwTBj
— Latish (@Latish) June 7, 2017
I am enjoying being a dad, though it does leave less time for geekier pursuits. Our puppy Dexter also continues to be a blessing, and we love having him as part of our family.
Dexter was part of our family photo session this week. pic.twitter.com/DNAc5wyLRi
— Latish (@Latish) May 4, 2017
I am very grateful for the life and blessings we have right now. There’s always room for improvement though. Next year, I would like to:
The Way of the Essentialist isn’t about getting more done in less time. It’s about getting only the right things done. It is not a time management strategy, or a productivity technique. It is a systematic discipline for discerning what is absolutely essential, then eliminating everything that is not, so we can make the highest possible contribution towards the things that really matter.
In DEEP WORK, author and professor Cal Newport flips the narrative on impact in a connected age. Instead of arguing distraction is bad, he instead celebrates the power of its opposite. Dividing this book into two parts, he first makes the case that in almost any profession, cultivating a deep work ethic will produce massive benefits. He then presents a rigorous training regimen, presented as a series of four “rules,” for transforming your mind and habits to support this skill.
Researcher and thought leader Dr. Brené Brown offers a powerful new vision that encourages us to dare greatly: to embrace vulnerability and imperfection, to live wholeheartedly, and to courageously engage in our lives.
Living a brave life is not always easy: We are, inevitably, going to stumble and fall. It is the rise from falling that Brown takes as her subject in Rising Strong. Rising strong after a fall is how we cultivate wholeheartedness. It’s the process, Brown writes, that teaches us the most about who we are.
Fooled by Randomness is a standalone book in Nassim Nicholas Taleb’s landmark Incerto series, an investigation of opacity, luck, uncertainty, probability, human error, risk, and decision-making in a world we don’t understand.
Moonwalking with Einstein recounts Joshua Foer’s yearlong quest to improve his memory under the tutelage of top “mental athletes.” He draws on cutting-edge research, a surprising cultural history of remembering, and venerable tricks of the mentalist’s trade to transform our understanding of human memory.
Many of us insist the main impediment to a full, successful life is the outside world. In fact, the most common enemy lies within: our ego. Early in our careers, it impedes learning and the cultivation of talent. With success, it can blind us to our faults and sow future problems. In failure, it magnifies each blow and makes recovery more difficult. At every stage, ego holds us back. In an era that glorifies social media, reality TV, and other forms of shameless self-promotion, the battle against ego must be fought on many fronts. Armed with the lessons in this book, as Holiday writes, “you will be less invested in the story you tell about your own specialness, and as a result, you will be liberated to accomplish the world-changing work you’ve set out to achieve.”
In The Gifts of Imperfection, Brené Brown, PhD, a leading expert on shame, authenticity and belonging, shares what she’s learned from a decade of research on the power of Wholehearted Living–a way of engaging with the world from a place of worthiness. In her ten guideposts, Brown engages our minds, hearts, and spirits as she explores how we can cultivate the courage, compassion, and connection to wake up in the morning and think, No matter what gets done and how much is left undone, I am enough, and to go to bed at night thinking, Yes, I am sometimes afraid, but I am also brave. And, yes, I am imperfect and vulnerable, but that doesn’t change the truth that I am worthy of love and belonging.
I do all my development in Vim, so I had never used Nuclide before finding this feature. Nuclide is a package from Facebook, built on top of Atom, to provide an IDE like experience for React Native development. Once you install Atom, and the Nuclide package, you can open your source code directory as a project. Then attach your debugger using the command palette.
Run your app in the simulator, and enable the React Native UI Inspector in Nuclide using the command palette.
Now, if you enable the UI Inspector in the simulator, it’ll highlight the elements in your simulator UI inside Nuclide.
This might work only with React Native 0.43 or higher. Install react-devtools as a dev dependency to your project.
1
|
|
Add the following to your scripts section in package.json
1
|
|
Start react devtools
1
|
|
Run your react native app in the simulator, and open the UI Inspector. The simulator will automatically use react-devtools as the primary UI for the UI Inspector.
P.S I learned about React Native basics from this Pluralsight course.
]]>Using the react-native-orientation package, you can detect orientation change, and also do a bunch of other things such as locking/unlocking to a certain orientation. I have used this successfully in the past with code that looks something like this (after installing the package):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
However, as of today, this seems to work on iphone but not on android. I tried to go through the issues list on Github, but could not find a solution that worked for me. This led me to another approach that I ended up using right now.
Rather than rely on another package, if we add an onLayout handler on the top level view, we can detect orientation change because this gets fired every time the device rotates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
P.S I learned about React Native basics from this Pluralsight course.
]]>
Dexter enjoying the weather
I gave up on authoring a Pluralsight course for now, as I could not find a topic that I have expertise in that would be a good fit for Pluralsight. I also did not create any new side projects this year, though I have started working on a small new one slowly. I also did some work on SqlSmash.
Next year, I would like to:
Read On: Oct 2016
Reading Time: 7 hours
Rating: 8/10
In this book, Karen Pryor clearly explains the underlying principles of behavioral training and through numerous fascinating examples reveals how this art can be applied to virtually any common situation. And best of all, she tells how to do it without yelling threats, force, punishment, guilt trips–or shooting the dog.
We got a puppy this year (first time dog owners), and have no experience with training dogs. This book was highly recommended to learn the basics for animal (as well as human, to some extent) training, and does a good job at that. Applying the knowledge, however, is the hard part, and is something I have not been very successful at yet. But that’s my shortcoming.
]]>npm init
).
1 2 |
|
1
|
|
My .babelrc looks like this
1 2 3 4 5 |
|
1
|
|
1 2 3 4 |
|
If you have more than one folder to transpile, you can use the concurrently npm package to run multiple babel commands simultaneously.
* If you are using git and want to stop tracking your ‘app’ folder now, then you can do that using
1
|
|
npm run watch
command, which will watch for file changes and automatically transpile the changed files. Before building your ExtJS code for deployment, you want to run npm run build
(probably on your build server).