Ionic 4 and MobX

I just spent several hours debugging an issue and hopefully, this will save you a lot of time.

I’m building a new Ionic 4 app and I’m using MobX to handle state.

I had previously used it in an Ionic 3 app, but I don’t think I was using it correctly.

This time I wanted to make sure that my pages & components worked with ChangeDetectionStrategy.OnPush.

The tutorials I found showed something simple like this:

Now I’m not doing inline templates, but I’d make sure I was using @observable and @computed properties. However, whenever I put *mobxAutorun on an element, the entire element disappeared.

I made sure I had MobxAngularModule imported in app.module.ts but nothing I did made a difference.

Finally, I found the issue.

You need to import MobxAngularModule in the page module as well.

As soon as I added it everything started working as expected.

How to Develop with Laravel Homestead

Are you interested in Laravel but don’t know how to start? Homestead is a Laravel project that simplifies the creation of a local environment configured to run Laravel applications. Bring your laptop and when we’re finished you’ll have Homestead running and a fresh install of Laravel ready to work with.

Recorded live at Madison Laravel on June 8th, 2017.

Notes

What is the best way to use DomainSession in a command line environment?

Jory Geerts asks:

Do you have any thoughts on how [DomainSession] could be used from a CLI environment?

The first thing to ask yourself is how would you like sessions to work on the command line? There are a few ways this could work.

Each run has its own new session

The main reason I see for this option would be to reuse the domain logic from your web app and it depends on DomainSession. You don’t really care what gets stored in the session because you consider it temporary.

In bin/with_new.php I’ve defined a very simple script.

First, I init the script. In this case, since I’m using a Radar application, I just use Aura.Di directly to load DomainModule. This makes sure I have SessionManager and Home configured.

If I was doing this in production, I’d probably have a different definition for DomainModule that I used with the CLI that used the Memory storage instead of File storage. In this example, I won’t worry about that.

Then I can get a new instance of my domain object Home and call it with null as the $sessionId. This will let the SessionManager generate a new ID for this request.

Each run has its own new prepopulated session

If I need to prepopulate the session with data (like a logged in user) I can simply start a new session, assign the values I want to the session and finish it like normal. Then I can grab the session ID from that session and pass it into the domain object so it can reuse that session.

I implement this in bin/with_prepopulated.php.

Reuse the session between script runs

The next option would be if you wanted to reuse the session between script runs. You’ll need to determine how you want to store the $sessionId between script runs, but one way would be to print it in the output, then include it as a parameter when calling your script in the future.

I implement this in bin/with_reused.php.

The output would work as such:

Summary

These three ways illustrate some of the ways you could to go about solving this issue. There will most likely be specific requirements based on your application, but it will most likely be some variation of these. For instance instead of printing the $sessionId you might store it in a file.

What do you think? Let me know in the comments if you see any problems with these approaches.

What is the best way to handle sessions with ADR?

Right before Christmas, I reached out to Paul Jones asking:

I’ve reached a point with a couple of my Radar projects where I need to add a login and set permissions. I’m trying to figure out the best way to handle this, especially with PSR-7 and ADR.

This led to discussing how to do sessions properly in Radar. I had read Paul’s post PSR-7 and Session Cookies which discussed how to tweak PHP Sessions to work better in a PSR-7 architecture. You don’t really want PHP automatically sending and reading cookies outside of the Request object.

Paul responded:

Finally, the more I work with separated domain layer, the more I dislike the built-in PHP session system. Lately, I have started to consider avoiding it entirely, in favor of something like a custom DomainSession. Attached are my very rough notes-in-code; maybe they’ll be useful to you.

Needless to say, they have been very useful. Paul has been incredibly generous with his time and after going back and forth through several rounds of refactoring and revising I’m ready to officially announce Cadre.DomainSession. The current version as of this post is 0.4.0.

Why DomainSession?

The reason for this package is that as Paul had said: “Anything that touches storage should be considered domain-layer work.” so it’s ok to read the session cookie in an Input class, and it’s ok to write the cookie in a Responder class, but pretty much everything else should be in the Domain layer.

For more information about Radar see Radar Under the Hood.

What does it do?

Cadre.DomainSession takes a session id (or generates one) and loads session data from storage. It’s smart enough to handle regenerating session ids and cleaning up expired sessions.

Demo

I’ve put together a small demo app using Radar and Cadre.DomainSession at radar-domain-session.

Loading the Session ID From a Cookie

Reading the session ID from a cookie is handled in the Input of your route. I used the excellent library dflydev-fig-cookies to simplify getting and setting cookies in PSR-7.

In Application\Delivery\DefaultInput I read from the SESSION_ID cookie, returning null if it doesn’t exist.

Starting, Using and Finishing the Session

In Application\Domain\Home I first inject the Cadre\DomainSession\SessionManager. Then I start the session with the session ID I passed in from the Input. I check to see if there is a timestamp session value (Unknown if not present) and assign it with the current timestamp. Finally, I finish the session which is what persists the data to storage. In this case, it’s just to the filesystem. One important thing to note is that I have to return the session object in the payload for the final step.

If you want to regenerate the session ID you can do so by calling $session->getId()->regenerate().

Persisting the Session ID in a Cookie

In Application\Delivery\DefaultResponder I check to see if there was a session in the payload. If there is, I check to see if the session ID has been updated (new or regenerated session id). If it’s been updated I persist the session ID value to the session cookie I’m reading from in the Input and that’s all there is to it.

Concerns

I have some concerns with this library. The built-in session handling has withstood the test of time. It’s been looked at and I assume many security concerns have been fixed. I’m not a security expert, so I worry that there are vulnerabilities in my code.

In particular, I’m using what I consider to be a fairly naive method for generating session IDs.

I need to do some research and find if session_create_id would be a better method to use. I’m not sure if it just generates an ID or if it depends on the storage implementation.

Summary

When you’re using ADR, it’s important to be absolutely clear what is and isn’t part of your domain. Paul considers anything that touches storage as domain-layer work. Reading and writing cookies is an implementation detail that is part of the delivery mechanism. Imagine using the same domain objects in a command line application. You wouldn’t use cookies, but perhaps you would pass a session ID in as a command line argument.

What am I missing? Do you find this implementation useful? Let me know in the comments.

UPDATE: There is also an interesting conversation going over on Reddit.

What is the best way to inject a logger?

I’m working on several projects right now that I’d like to be able to generate logs from.

The problem is that logging isn’t required for the code to work, so how do I configure it?

I see three possibilities:

Required in Constructor

Pros

  • Cleanest implementation

Cons

  • Requires user to pass in a logger even if they don’t want to log anything

Optional in Constructor

Pros

  • No longer requires the user to pass in a logger

Cons

  • Clutters up the constructor
  • I consider using null a code smell

Optional setLogger Method

Pros

  • Clean constructor
  • No nulls

Cons

  • Instantiating with a logger requires two statements

Summary

I’m leaning toward the third method for my packages even though it doesn’t feel like an ideal solution. It just feels better than the other two.

How are you handling injecting an optional logger? Let me know in the comments.

PSR-7 Objects Could Be Immutable

I’ve been thinking a lot about immutable objects lately. Yegor Bugayenko claims that Objects Should Be Immutable and PSR-7: HTTP message interfaces are designed to be immutable.

Messages are values where the identity is the aggregate of all parts of the message; a change to any aspect of the message is essentially a new message. This is the very definition of a value object. The practice by which changes result in a new instance is termed immutability and is a feature designed to ensure the integrity of a given value.

There has been some discussion around the mutability of streams in PSR-7.

Andrew Carter wrote a post discussing why PSR-7 Objects Are Not Immutable saying:

You shouldn’t expect to see the message that was written to the response actually rendered. The code we have written explicitly avoided returning the response by throwing the exception. However, if you disable the Whoops error handler and use the default templated error handler you will find that your message still appears at the top of the error page that is generated by the framework.

Paul M. Jones mentions the immutability of streams in Avoiding Quasi-Immutable Objects in PHP.

If a stream or similar resource has been opened in a writable (or appendable) mode, and is used as an immutable property, it should be obvious that object immutability is not preserved.

This makes sense. If you write to a stream, then rewind it and write it, the value has changed.

I don’t think this makes the class wrapping the stream mutable.

Yegor talks about this idea in Gradients of Immutability.

His argument would be that the object isn’t a constant, but it is immutable.

The object isn’t representative of the content of the stream, but of the reference to the stream.

It’s like if you had an object that interacted with a file.

You might argue that a File object isn’t immutable because if it was $f->read() should have returned “hoopla”. But I disagree.

The File object is wrapping a file name, a pointer to a file in the file system. The object isn’t constant, but it is immutable because it’s data is the file name and not the contents of the file.

I’d be breaking immutability if I added a setFilename method that allowed you to change what file the object was pointing to.

Zend Diactoros

The PSR-7 implementation that I typically use is Zend Diactoros because it’s what used by Radar.

I was hoping to dig in and show how it actually is immutable, but I can’t. Because it isn’t. 🙁

It could have been, but the Stream::attach method makes it mutable.

The strange thing is that it implements Psr\Http\Message\StreamInterface which does not define an attach method.

So Zend\Diactoros\Stream chooses to define additional methods that are not part of the PSR-7 interface, and in doing so, breaks immutability.

Guzzle PSR-7

Looking at other implementations, it would appear Guzzle PSR-7 streams are immutable.

How Can We Colonize Mars?

I periodically read about people wanting to colonize Mars. Elon Musk seems interested in doing so. However, I’m always confused on how we can actually do that, but not in the technical sense.

According to the 1967 Outer Space Treaty, we’re forbidden from sending a mission, robot or human, close to a water source in the fear of contaminating it with life from Earth.

Isn’t colonizing a planet basically the definition of “contaminating it with life from Earth”?

I’ve always thought that it made a lot more sense to create a self-contained spaceship that people would live on indefinitely. They would have to be big enough to hold at least 10,000-40,000 people in able to preserve genetic diversity.

We could send out several of these each in different directions with the idea that only one needs to survive for the human race to continue.

The objective wouldn’t be to reach someplace specific, it would just be to continue to live, breed, develop culture, etc. Eventually, there would be a need to create more ships so landing on planets or meteors might be needed, but only for raw materials, not to colonize.

Some people along the way may decide to stay on a planet, but frankly, they would probably die unless it was a whole lot of them.

Be the Change

Donald Trump will be the next president of the United States.

There will be a lot of negativity in the coming days. A lot of finger pointing, name calling, blaming and possibly violence. Please don’t participate in the negativity.

When people succeed they tend to party but when they fail they tend to ponder. –Tony Robbins

This is an opportunity to listen to each other. A large part of our country spoke last night. They are tired of being ignored, they are in pain. They want what all of us want. To be loved and to provide for themselves and their families.

They feel that Donald Trump is the best chance they have to change a system that they feel is hurting them. A system that is hurting their families and communities.

As a nation, we now have the opportunity to listen to each other. To understand each other and do the best we can to move forward and make this country great for all of us.

If you’re like me and are scared about what this election means for our families and communities. If you’re scared of what it means for people of color, for women, for LGBTQ people, for Muslims and Jews. Take comfort in all the good in the world.

I think that many Trump supporters are kind, caring, thoughtful people. They are not the racist, misogynistic monsters portrayed by the news.

Don’t ask why is this happening to us. But what opportunities does this present for us all to be the change we want in the world?

When I was a boy and I would see scary things in the news, my mother would say to me, “Look for the helpers. You will always find people who are helping.” –Fred Rogers

Do not shut out your friends, family or neighbors who voted differently than you yesterday. Listen. Don’t lecture or try to convince. Just listen. We are more common than different.

What is the best git workflow for small teams?

In my development, I use Git all the time. It was a little tricky to figure out at first but, I feel like I have a good understanding of how to use it.

When I’ve worked with other developers I see them struggling with a few concepts that I use regularly and thought it might be helpful to document my workflow.

On our team, we use feature branches and pull requests. I don’t have a strong preference of whether the feature branch is in our main repo or in a developers fork of our repo. For this post, I’ll assume feature branches are in the main repo.

Let’s start with the following master branch.

I’m going to work on a new feature so I create a new branch off of master and start committing my changes.

During that time, other developers merged in features.

I’m ready to submit my PR, but first I need to rebase off of master, potentially resolving conflicts that emerge.

I need to make changes based on a code review, so I commit those to my repo. Meanwhile, other features are merged into master.

Before I have my new changes reviewed I once again need to rebase off of master.

To push up to the main repo I need to do a force push because I’m overwriting what was previously there.

My PR is accepted, so it’s squashed and merged into master as H (via GitHub), the feature branch is deleted.

Once something is merged into master it’s locked. Other than specific edge cases, you shouldn’t ever have to force push to master, only to feature branches.

With our main SaaS applications I also use Git to deploy to staging and production. I wouldn’t use this for library development or any applications that have multiple deployments.

I have special branches staging and production which our continuous integration platform watch. When I push changes into those branches they are tested (as with all pushes) and if tests pass, they are deployed to that environment.

So if we wanted to deploy my latest feature, I’d merge it into staging and have our team review it to determine if there are any issues that need to be resolved before deploying to production.

If there are changes we create a new feature branch and start at the top of this workflow.

If there are no changes to be made then we merge into production, it’s tested and deployed.

That’s it! Developers I’ve worked with tend to get hung up on rebasing. I know some workflows never rebase and always merge, but I strongly prefer keeping things clean with rebasing.

I know that there are a million ways to use Git and different teams have different workflows. What do you think of my process? Anything you’d change?

Using Action-Domain-Responder on the command line

I’ve created a new proof of concept ADR library that works like Radar, only for the command line interface.

Yesterday I was working on a project in Radar and needed to create a command line tool for it.

In the past, I’ve always used Symfony Console which I like. Since my application was already built using Radar and adhering to Action-Domain-Responder and Clean Architecture, I wanted a solution that was more consistent with the rest of the codebase.

The selling point to Clean Architecture is that your domain logic is separate from the delivery mechanism. So if Radar was my delivery mechanism, I should be able to have a different command line delivery mechanism and my domain shouldn’t know or care.

I took a look at Aura.Cli which seems nice. However, it’s very much a command line library. Out of the box, it’s not a framework for building command line tools adhering to ADR.

So I took a stab at writing one (that uses Aura.Cli), it’s called Cadre.CliAdr.

At this point, it’s more of a proof of concept rather than a production solution. It’s heavily based on Radar and uses the same patterns.

Here is an example of how you’d use it. It will seem very familiar if you’ve used Radar.

Expect revisions and documentation to come. In the meantime, please post any comments here or as an issue on GitHub.