Safari blocking new window opened from clicking button in web application

I work on a web application that includes a feature that integrates with another of my company’s products. You trigger the integration by clicking a button in the first web app, which launches the second web app and passes along a document. The code is a little something like this:

$(document).on('click', '.my-button', function(e) {
  $.ajax({
     method: 'POST',
     url: '/api/call/to/get/the/url/we/need/to/open',
       error: function (status, err) { },
       success: function (data) {
         window.open(data.redirectUrl);
        }
     });
});

I mostly use Chrome on either a Mac or Linux laptop and this has worked fine. But yesterday I got a report that the button was not functioning on Safari. Turns out that the window.open was being blocked by Safari’s popup blocker. Of course, the easiest thing is to just tell the user to turn off their popup blocker. But that’s obviously not ideal.

So I did some digging and found other people had run into similar issues with Safari. But the solution is relatively simple, according to this StackOverflow link. Do the window.open first, with no target, and then set that window’s location.

However, this still didn’t fix the issue for me. Digging a little deeper into the comments on the post, one additional thing I discovered is that the ajax call that’s triggering this also needs to _NOT_ be asynchronous. Well, this is not ideal, but the web app is basically blocked until this completes anyway, so this turns out to be a good enough solution for now. The API call is pretty fast, but I throw up a little temporary modal with a spinner while this is being processed so the window doesn’t just completely freeze up with no feedback.

So the fixed code looks a little like this

$(document).on('click', '.my-button', function(e) {
  $.ajax({
     method: 'POST',
     async: false,
     url: '/api/call/to/get/the/url/we/need/to/open',
       error: function (status, err) { },
       success: function (data) {
         var newWindow = window.open();
         newWindow.location = data.redirectUrl;
        }
     });
});

Hope this helps someone! And of course I welcome any feedback on better ways of handling this.

Yesterday

Disclaimer: this post has nothing to do with the Beatles song.

TLDR at the bottom!

This blog has been languishing for awhile.  I still get quite a few hits for a post I wrote ages ago for a problem I had getting my Logitech mouse to work with Ubuntu, and I even occasionally get comments from people thanking me because it helped them out. It’s nice to know at least it’s not completely lifeless and some others are still finding value in this blog!

However, I’ve had the itch to start posting again.  I was inspired by this YouTube video and I’ve decided to start sharing random things I learn in the hope of educating others too.  Most of it will probably be programming related.  I’ve been in this game for many, many years, but there’s always a ton more to learn.  Not just learning new tools and frameworks, but learning little things you didn’t even know about things you use every day without taking the time to dive deeper until you need to.  Now, I’m not promising to actually post daily, and a lot of these are probably just going to be quick little things, but I’m definitely going to try to post more regularly.

Anyhow, the title of this post has to do with getting yesterday’s date from the command line!

I have a log parsing script that I’ve been running manually as a two step process.  Step 1 is running a command to download the logs from the previous day from AWS Cloudwatch.  Step 2 is running my actual parsing script for that same date to generate the analysis I’m looking for.  In each case, I need to pass yesterday’s date to the script.

I just wanted to write a simple bash wrapper script to run those commands.  Now it’s really easy to get today’s date:

./some-script.sh `date +"%m/%d/%Y"`

Anybody familiar with bash can probably work that out. First it runs the date command, given the format string so that it returns “07/16/2019”. Then ./some-script.sh gets executed with that as an argument.

But what if I need yesterday’s date? My first thought was that I could extract the date portion from the string, and just subtract one from that. Simple, right? Except, what if the day I’m running the script happens to be first of the month? Or even worse, the first of the year? Ugh! Now it’s getting complicated. There’s got to be an easier way to do this, right?

Yep!

If you have the GNU version of the date command, just do one of the following (H/T to this StackOverflow post)

date +"%m/%d/%Y" -d "yesterday"
or
date +"%m/%d/%Y" -d "1 day ago"

I was very excited to find this! I use Linux at home and for personal stuff, but at work I’m using a Mac, and unfortunately the OSX version of the date command doesn’t recognize this option.

But do not despair! On OSX the syntax is just slightly different

date -v-1d + "%m/%d/%Y"

In both cases, you can do more than just yesterday’s date. You can go multiple days in the past or the future. I’ll leave that as an exercise to the reader to work out.

Hope someone else finds this helpful!

TLDR:
To get yesterday’s date from the command line:
GNU/Linux: date +"%m/%d/%Y" -d "yesterday"
OSX: date -v-1d + "%m/%d/%Y"

SOLVED: Docker Networking On Fedora Linux Fails When I’m Connected To VPN

I do a lot of my development work inside docker containers.  Recently I ran into an issue where, when connected to my company’s VPN network, the docker containers on my local machine running Fedora would lose the ability to connect to external resources.  Eventually I discovered the issue was that the default subnet created for the docker bridge interface on my Linux machine was overlapping with the subnet used by our corporate VPN.  So everything worked fine, as long as I wasn’t connected to the VPN.

My home network is a 10.x.x.x subnet, while my corporate VPN (and my default docker bridger interface) were bothing using 172.x.x.x.  So I opted to use 192.168.1.x for my docker bridge.  Making the change was fairly straightforward.  I needed to create the file /etc/docker/daemon.json.  The documentation describes a lot of options in this file, but all I needed was the following:

{
 "bip": "192.168.1.1/24"
}

Then I restarted docker:

sudo service docker restart

Problem solved!

 

Initial Impressions of DirectTV Now

I’m a pretty happy user of Playstation Vue, especially since they recently released an AppleTV app.  But I can’t help but be tempted by the value proposition of DirecTV Now, particularly with their introductory offer, so I decided to sign up for the seven day free trial.

For me, it was great when I was streaming on my Apple TV in the mid/late afternoon. I also briefly tried the iOS app on my iPad and my iPhone.  After playing around for a few minutes, I left it playing in the background while I did some actual work.

No hiccups, until around 6:30pm, I got an error message about exceeding my streaming limit, even though the only stream I had running was on my Apple TV. I thought maybe the apps on the iPhone and iPad were still registering as connected somehow, even though they were no longer actively being used, so I force quit the application on both of those devices. The error message persisted.  Then, I force quit the application on my AppleTV and restarted it.

The first time I restarted the application, it reported that the service was “temporarily unavailable”.  I couldn’t do anything in the app at that point; there was no retry option. So I force quit again. This time it loaded up, and all seemed well, until a few minutes later when I got the error about exceeding my streaming limit again.

I discovered that if I switched channels, it would come back temporarily, but within a couple of minutes the error would reappear. The message referenced a particular error code to look up in their help center if the problem persisted. Unfortunately, all the help center did was basically repeat the error message: you can only have two streams active at a time. Duh.

I tried watching for another 15-20 minutes but finally gave up since the error kept reappearing every couple of minutes.  I switched back to my trusty PS Vue app for the night.

I’m glad they have a 7 day trial. I’m still on the fence. I love the value proposition and the number of channels (especially the +$5 for HBO which I pay $15/mo for now), but I really use the Cloud DVR a lot on PS Vue. I know they are supposedly adding a cloud DVR feature in “2017”.

Hoping that it was just capacity issues related to it being launch day.  We’ll see what day 2 brings.

Limited Edition IPhone 7+ with Wireless Charging

iPhone 7+ Charging on Samsung Wireless ChargerAfter experimenting with Android phones for about the last year and a half, I decided to switch back to iOS. I have no desire to engage in fanboy flamewars.  Android and iOS have their pros and cons, but for me, the applications I use regularly and the ecosystem I work in, iOS is just a better fit.

One thing I knew I’d be losing switching to the iPhone is the headphone jack. I know that bothers a lot of people, but for me, it’s not an issue because I’m a big fan of Bluetooth headphones.  On rare occasions, when I do want to use wired headphones, I use a Bluetooth adapter.  The one thing my Galaxy S7 Edge has that I really was going to miss was the convenience of wireless charging.

Despite all the talk about how awesome a world without wires is at the iPhone keynote, I was disappointed that Apple chose not to add wireless charging as a built-in feature of the new hardware.  Luckily, that turned out not to be much of an issue after all.  I found this wireless charging pad that plugs into the lightning port and sticks onto the back of your iPhone.  Obviously, it doesn’t look all that great on the back of your phone, but I bought a very inexpensive case which adds a little bit of grip and protection, and makes the charging pad pretty much invisible.  The case is thin enough that it doesn’t interfere with wireless charging at all.  A thicker case, or one with a metal plate for sticking to a magnetic mount probably wouldn’t work as well.  Wireless charging works great with the Samsung chargers I already have,  and the charging pad actually comes with its own wireless charger if you don’t already have one.

The only potential drawback is that if you need access to the lightning port on the phone for some reason, it would be kind of a pain to deal with.  In my case, the only thing I use the lightning port for is charging, and since I can do it wirelessly now (even away from the home or office) it’s not an issue at all for me.  It’s an inexpensive upgrade and I’m quite pleased with it!

20161023_104333 Back of the phone with charging padBack of Phone With Case Covering Charging Pad