You got your HTML in my Javascript!

I do love that bit.  Anyway, I’m with Officer Reeses.  Not on the whole “murder car accident victims and take their idea” front, but definitely that two great tastes can taste great together.

Most of my frontend work so far has been in Angular 1.5 and 2 (and of course, regular JS and jQuery in the good old days).  I’ve really been liking Angular 2 (may have mentioned that previously)- when paired with Typescript, it really makes for a nice dev experience.  I know es6 classes is somewhat controversial, but it’s nice as an organization tool for code if nothing else.  Having that class grouping and inheritance (I know it’s just a wrapper on normal JS prototyping, but it’s still nice), as well as a module system for easily including code/components from other files allows for small, related groupings of code more naturally (at least, in my opinion).

However, I’ve also started getting up to speed on React and so far I’m really loving it.  Using the Babel transpiler (or, I guess you could use Typescript in React as well- though it’s not as common), you can take advantage of classes and module loading and all that other goodness.  React seems a bit less of a wrapper than Angular does- example: There is no *ngFor looping in React- if you want to loop over an array of items and display them in a view, you just use a good old array method (map, forEach, etc).

And I think that’s where some of the Angular vs React argument comes from.  Do you prefer more html in your javascript or more javascript (or Angular’s version of javascript) in your html.

Having worked with one and dabbled so far in the other, it really seems like a toss up.  Once you’ve created a few modules in each, each approach seems to make good sense.  It would really just be a personal preference- but both make it easier to create the quick, responsive web apps people are starting to come to expect (unless you visit any food blog or other site littered with ads- those are just terrible).

So, did Angular get Javascript in your HTML?  Did React get HTML in your Javascript.  Who cares?  They’re the great tastes that taste great together!

A Simple Kind of Man

One of the cool parts of most Javascript frameworks these days is templating.  Each one approaches is a bit differently- React has you write jsx- basically html in your Javascript file.  Angular has you write Javascript in your html files- binding to events and interpolating variables.  Hell- you can even create your own templating system without too much trouble with ES6 templating strings.

In general, this is useful for the developer writing the code and the developer reading the code.  The writer has access to variables, functions, and other functionality right in the html.  You can perform simple logic checks, math, and even use ternary operators as well.  The reader can usually see what the writer was intending and has an easier time updating and extending the functionality.

I said ‘usually’ because I did manage to make an html template loop in our Angular 2 application that is quite hard to understand.  I guess no framework is completely foolproof.

Angular allows for looping in templates: *ngFor=”let item of array” allows you to loop over an array and display the info (I believe you can also iterate over an object’s keys, though it requires a custom pipe).  In my case, I used it to finish the display aspect of a pagination feature.  The template for loop iterates over the array of page numbers and displays each.  Throw a (click)=”setGrid(start)” on each one, and you have paging functionality.

But it got more complex.  The array contains the number for the first item on each page.  So, if the user has it set to display 10 items on a page, the array for the first 5 pages is [1, 11, 21, 31, 41].  They can change that, so if they have 50 items on a page, it’s [1, 51, 101, 151, 201] – you get the idea.  The number that should actually display, however, is different: 1, 2, 3, 4, 5.  So, setting up the onclick functionality was fairly simple- pass the actual number in the array and you’ll get the listing starting with that item:

*ngFor="let start of paginationArrayDisplay"
(click)="setGrid(start);"

Works fine- but how to display the correct numbers. Well, that’s not too complicated either.  You can take the ‘start’ variable (the number for the first item on the page being navigated to), subtract 1 to account for the zero indexing, then divide that by the maxItemsOnPage variable (a variable tracking what the user has set to be the number of items displayed on one page) plus 1 (to account on that side as well).  So, if it’s page 3 (start = 21, display should be 3), you would get 21 – 1 (20), divided by 10 (2) plus 1 (3!).  Maybe not super simple, but nothing crazy, and it works.

But then there’s an edge case – page one.  If you follow the formula above for page one, you get zero (1 – 1 = 0 and 0 divided by anything is 0).  Again, not a complicated case, but it has to be accounted for in the template loop.  I tried moving all this logic to the component instead, but doing so only loops the same page number over and over (so your page navigation buttons work, but all display “1”).

Long story short (too late!), this is the code that displays the page number in the for loop in my template:

{{(start - 1) / _paginationService.maxItemsOnPage === 0 ? 1 : ((start - 1) / _paginationService.maxItemsOnPage) + 1}}

Ugh. I don’t like looking at that.  If the formula spits out zero, it sets the page display in the numbering list to 1.  Otherwise, the number it spits out is the correct page number.

I bike to work most days.  This is not bragging- I don’t do it out of any sense of environmental conservation, I just can’t stand driving and/or parking downtown.  But it gives me about 30 minutes of podcast listening.  Recently, I was listening to The Changelog– a great podcast that interviews programmers about various topics- but generally about their life story.  One recent episode interviewed Sandy Metz – a veteran programmer and writer.  She had great thoughts about code complexity- we all hate to do it, we all hate to read it and try to figure it out when others do it, but sometimes, it’s necessary.  Programming can be a complex process- and though this used to be the realm of the backend dev, Javascript frameworks have pushed it into the world of the frontend as well.

So I’m keeping my complicated html template logic for now.  Maybe someone will fix it in the future and they’ll get to see my <!–SORRY ABOUT THIS–> comment.  Maybe it will make them smile instead of cursing my name.

Probably not, but maybe.

Nonbreaking Nospace Space

Recently, we’ve switched gears on the new project.  Still using Angular 2 as the front end, but the backend had to change- moving away from Python/Django to C#/.NET.  However, there was one cool feature/tricky quirk in Django I wanted to share.

Google plays a huge role in building a new website.  We definitely didn’t consider their ranking and site score index nearly enough in the planning stages.  As a result, we had multiple post-launch ‘fixes’ to the new site- all related to getting our site as Google-friendly as possible.

One of those involved minification.  Sure- everyone knows that minifying your Javascript and CSS files is important.  It keeps the overall size of each http transfer low- meaning: faster load times.  Add concatenation to that process and you’re also reducing the overall number of http transfers- meaning: faster load times (at least, until http/2 becomes the standard- it looks like that will allow for many more open connections during the transfer process- meaning: many things that have become standard about site speed best practices will change).

But Google will also knock your page speed score down if you don’t minify your html.  I hadn’t heard of that one before.  The size differences really didn’t seem like they’d make much difference- a few bytes here and there- but it doesn’t matter to the Google check.  If your html isn’t minified, you will lose points.

In steps Django.  There’s a great middleware feature: htmlmin (pretty sure you can just install it with pip and add it to the middleware array on your settings.py file).  It will automatically minify all your html templates.  Very useful- but there is one ‘gotcha’.

It’s possible that while you were creating your masterpiece of a website, that some ‘nonbreaking nospace’ spaces were inserted.  How does this happen?  I’m still not quite sure- generally it’s because a file has been saved in utf-8 (generally a good thing) but with BOM encoding (not sure what that is or why it really matters).  However, if you do have one of these stray characters in the minified version, it will create a blank white space on your site (usually at the very top)- the height of a normal character.

The offending character code is &#65279 – but you won’t be able to find it if you search your .html files.  You can delete every space on your file as well- it won’t help.  It appears that the only (or at least easiest) way to fix this is to open your file in notepad++ (a free download), change the encoding to simple utf-8 (no BOM) and save.

This won’t make any visible change to your html code, but it will eliminate the issue and remove the blank space.  And your html is minified!  And Google is happy!  Now I just need to optimize that 6kb icon image down to 4.75kb and we’re in SEO heaven!

Drop the Base

It’s an unfortunate fact that some users out there are still on old versions of Internet Explorer.  Despite Microsoft’s recent efforts to finally put them down and sweep any memory of their existence away, developers still have to ask that hard question:

“Do I really need to support IE7/8/9?”

I really want to say ‘no’.  If we all just say no, everyone will have to upgrade and we can drop all the ugly hacks, workarounds, and so on from our code.

But that perfect world isn’t quite here yet.  So I got to spend some time making our Angular/Django app work on IE7/8 (Angular is pretty good with 9- though there is one cool/crazy bug below).  My answer?  Set up a conditional comment to check for IE < 9.  If true, a Django route takes over, redirecting the user of an antiquated browser to our back up page- just a basic notice of what we do, with a simple contact form.

Modern browser users will never see this ugly piece of crap.  Is it the best answer?  I don’t know- but it does work.  And it was kind of fun re-living some of the old hacks (I started developing more into the IE9 phase, but legacy support, blah blah blah).  Our lead didn’t want to use Jquery (I really like jQuery, so I resisted, but there are good reasons to leave it out of an Angular project- coming in a future blog!), so I had to go look up the old syntax for getting elements from the DOM.  I remember that getElementById works even that far back, but always forget that the entire back half of innerHTML is capitalized.  And actually- knowing I only needed to support IE meant that it wasn’t that hard not using jQuery.  You don’t get all the cool animation type stuff that’s built in, but from a functional standpoint, it worked pretty well.

Except one little thing.  Back to the IE9 bug.

Because we decided to let IE9 users access the full app (Angular officially supports 9), I didn’t set up a redirect- IE9 users go to the homepage and can access the whole shebang.  However, some of our Angular routes just weren’t working.  The view section was blank.  Checked the devtools and saw I was getting a 404 not found from Django on my partials that should have returned the proper template.  Worked fine in FF/Chrome/new IE, so I couldn’t for the life of me figure out what was going on.

Turns out, IE9 ignores the html <base> tag.  It seems to have no effect if you just drop it in your code as normal, so the links within the app weren’t using the proper relative path- they were trying to look in the same ‘folder’ (which didn’t exist).

After some Googling (thanks Stack Overflow), I found that answer above.  And a cool trick- just set the base tag, then directly below, add a simple JS function to add the base tag again.  Started working perfectly after that.

 

fix is easy js iife- but how long would it have taken me to figure out if not for the internet!

Non breaking spaces are breaking my balls

We’re still working on the search function.  The little preview text section seems to be coming through properly from the back end now, but I kept getting weird ‘character not found’ placeholders in the text.

You know- the graphic that shows when the browser doesn’t recognize the character.  It’s a ? inside a little black diamond.  In this case, it was the ‘&nbsp;’   – a non breaking space character.

I’d written a few regex checks in the php code to strip out certain things from the search results.  Anything inside style or script tags and any html code. Ok,fine – in truth, I hacked together these regexs in a terrible fashion.  There were angle brackets and backslash body parts all over my monitor.

Then, I threw the code sanitized results through a html_entity_decode call to make sure everything looks right.  But those stupid ? diamonds were still there.

Naturally, I thought something was wrong with my regex checks.  I wasted too long trying to rewrite them before I thought to check into the default html_entity_decode function.  Turns out, it doesn’t decode the   character.  Also turns out, I should have read the php official documentation a little more closely, as it states:

the ‘ ‘ entity is not ASCII code 32 (which is stripped by trim()) but ASCII code 160 (0xa0) in the default ISO 8859-1 characterset.

I don’t really know what that means, except that it meant my function wasn’t working.  The nice part- the fix is easy, just do a str_replace to remove them, and make sure to do it in the right order!

Iceberg, right ahead!

There was a request from a client to add a new field to the tracking feature.  He wanted to be able to include address, title, description, date, and now name.  Traditionally, I recommended using the title field for names- it’s easy and the whole tracking category can be sorted by that field (as well as date and address).

But it also seemed useful, so I started on it, thinking “How hard can adding one little text field be?”

It didn’t take long.  It wasn’t too hard.  But it did teach me that even tiny edits (adding a simple text input field to a form) can have tendrils that snake out all over an application.  I added the field, but then it had nowhere to save to, so I had to edit the database.  Not hard- thanks phpmyadmin! But then there was the matter of sorting a category.  A branching if/else addition, with a little mysql query solved that.  Wait- there’s also an import option.  A user can import tracking entries via a spreadsheet.  New code would have to handle that, as well as the related export option.

In the end, adding one little text input field involved html (adding the field itself), css (styling the field), js (validity checking), php (working with the backend to save/display the content) and mysql (saving/displaying to the database).  Now I know why developers are hesitant to give a timeframe on anything- large scale web applications are a bit like icebergs- most of the stuff that’s going to sink you is below the surface.

More user shenanagins

Did I spell shenenagins right?  Probably not.

More work done on reorganizing and upgrading the user account creation screen for the CMS I’m working on.  ‘Above the fold’ is now the welcome message, help link, and basic user info (name, username, password, contact info, notification option).  Previously, the email info entry had been at the bottom- caused a good deal of confusion.

Then there are save options.  Setting up a new user requires an initial save after entering the basics, so this seemed like a good idea.

After that are the other options.  Home/directory/email list config.  Admin authorization options, etc.  These are much less vital (though home assignment is an important step).  Need to do a little sql magic to get the current info from the db for some items (directory privacy settings, current email lists subscribed to).  Then we will work out the rest of the client side js checks on the form itself.