That fresh inline style

React is cool.

I know- React is so 2016- but I’m generally late to the party anyway.  I’d read good things, but hadn’t had a chance to use it in an official project (you know, the ones that pay real money).  So I started a side project using React JS.

Generally, it seems more modular than Angular 2.  When working on an Angular 2 (which I love) app, the approach is usually “Angular all the things”.  You are going to make a single page app.  It is going to use the router and Typescript and so on.  Very nice to have your decisions made for you.

With React, I have a bit more flexibility- but have to make some more decisions.  I can use it just to create some reusable UI components (working on a React based form for my static main website now).  Or I can integrate with a router and create a full blown single page app.  I wanted to test everything, so for the side project (a collaborative event creation and commenting app for scheduling our weekly beer-drinking night) I’m integrating react-router and going full-blown SPA (single page app- without all the typing).

This post, however, is about a trap I fell into with styling the app.  I fall back to the OG Javascript days when getting going with a new framework- and it can lead to trouble (see post from a while ago about me trying to manipulate the DOM directly in Angular).  So, when I wanted to use JS to dynamically offset a static header, I tried to getElementById and failed miserably.

React (and Angular) has lifecycle hook methods.  When your view is loaded and the DOM is ready, componentDidMount fires.  It seemed like a good place to add my little function to get the header element height (which will depend on the width of the user’s viewport) and add that much padding (plus a little breathing room) to the main wrapper.

setHeader() {
    const header = document.querySelector('#header');
    const wrapper = document.querySelector('#content-wrapper');
    //have to make sure header exists or error
    if(header) {
        wrapper.style.paddingTop = `${header.clientHeight + 16}px`;
    }
}

Please note: the above is not exact- that version of the function is long gone, but should give you the idea.

And it did fire properly in the lifecycle hook.  But the height of the header wouldn’t always change.  Turns out- in React (like in Angular), directly manipulating the DOM is a Bad Idea.  I haven’t dug too deeply into this, though I would guess it has something to do with the diffing/shadow DOM aspect.  But there is a good and easy fix.

Don’t manipulate the DOM directly.  Part of the beauty of these front end frameworks is that you can dynamically set styles.  Some developers set all their styles directly in their jsx.  So, instead of the above function, I used this

//call inside componentDidMount so the DOM is ready
setHeader() {
    const header = document.querySelector('#header');

    //have to make sure header exists or error
    if(header) {
        this.headerHeight = header.clientHeight;
    }
}

And in the jsx, set the style’s paddingTop attribute to the end value of this.headerHeight.  I would display it here, but for some reason WordPress won’t let me show html tags.  Sorry!  But the moral stands- this method works.  Knowing the native JS DOM manipulation methods is very useful, but it can help to forget them sometimes when using a front end framework.

Also, if anyone knows why html tags cause such trouble, let me know!  I tried both the <code> and <pre> tags, but html just comes out blank (works with other kinds of code it seems).

The Copy/Paste Conundrum

We’re covering just a quick bit of refactoring today on the Devblog.  Next week we’ll be back to longer, rambling posting!

In our Angular application (which version?  remember- now It’s Just Angular!) we have a ‘setup’ module.  It allows an admin to edit certain values in the database (payment types, exchange rates, active states, etc).  Views in this module also include some reporting (charts, total items, etc).  In order to ensure everything updates when a change is made, we used a shared ‘setup.service’ class, stored the data as Behavior Subjects (each an array of objects that can be converted into an Observable with .asObservable()), then subscribe to the resulting observable in the components themselves.

I know Observables are usually though of as being used with ‘live’ data- coming from a database like Firebase, that can broadcast out updates in real time.  We don’t do that (we are using SqlServer), but found that Observables can still be useful in a single page application.  When data is saved in the ‘edit form’ area of the page, we can manually fire the Behavior Subject’s .next() function to get the latest data updated ‘live’ into the reporting area.

Anyway- that long intro was just to provide background.  The actual refactoring was in the setup.service class.  We have a whole bunch of Behavior Subject/Observable pairs initialized here (for all the types of data we want to update and subscribe to in this Setup section).  We also had multiple people adding methods for updating data to this class.  So, developer A creates a method for ‘getAuditTypes’ – to get a Json response with all the possible audit log types from the database.  It looked a little like this:

getTypes() {
    this._backendService.getData(CONFIG.auditTypesApiUrlBase)
        .subscribe(fetchedTypes => {
            this._activityTypes.next(fetchedTypes);
            this.getAuditCharts();
            this.getSetupBarCharts();
        },
        error => {
            this._notificationService.showNotification({ message: 'Error Getting Activity Types', type: 'error' });
    });
}

It uses a backendService method (which is just a helper to make sure the right authentication and headers are set on http requests) to call out, get the data, subscribe to the response, call the .next method with the new data and update any charts.  Works great- but as more views were added and data was being fetched, more of these methods were being added to the setup.service class (each person who worked with this file would just add a new method to get the data they needed).  In the end, we had almost 20 methods that were almost identical to the one above (with the exception of the api route and behavior subject name being called.  Great to get things working quickly (just a bit of copy/paste), but terrible for maintainability (edits or updates to the logic would have to be repeated almost 20 times).

So, we just refactored the method to receive a couple arguments.  Now there is one shared method to get data for the setup section (instead of 20).  It looks very similar:

getSetupData(apiUrl: string, nextTitle: string) {
    this._backendService.getData(apiUrl)
        .subscribe(response => {
            this[nextTitle].next(response);
            this.getAuditCharts();
            this.getSetupBarCharts();
        },
        error => {
            this._notificationService.showNotification({ message: 'Error Getting Activity Types', type: 'error' });
    });
}

Almost identical- except for a couple new arguments.  In the component (class) that uses this shared service, we pass parameters specific to the data being retrieved and the array being updated:

this.setupService.getSetupData('http://yourdomain.com/api/apiendpoint', '_behaviorSubjectName');

This way, we get the specific data we need to the component, but don’t have a whole bunch of unnecessary copied methods on the service.  Oh, and did I say this would be short and not rambling?  Too late… Sorry.

Reactular – Or, How I learned to Stop Worrying and Love JS

Aka: Why modern Javascript frameworks are sometimes like characters from Eyes Wide Shut, wandering around at an upscale swingers party…

So far, using React has been a lot of fun- but I have noticed a bit of a learning curve.  The basics are nice and easy- particularly with the ‘create-react-app‘ utility.  If you haven’t used that, definitely check it out- it takes away almost all the setup of the application (webpack config, dev server, etc) and lets you get straight to the coding.

Usually, I’m one of those people that wants to build everything myself to understand how it works, but there are a couple exceptions.  Working with calendars and dates is one- I’ll always use a module/plugin for that.  My brain starts melting even thinking about trying to get that right.  Setup for JS frameworks is another.  We had to do all the config for an Angular 2 project through the release candidates and now into production and it was a bit of a nightmare.  No fault to the Angular 2 (sorry, just Angular) folks- their framework is awesome- but setting it up was not easy.

Anyway, getting a ‘hello world’ app going in React is great, but if you’re going to use it for anything beyond really cool UI components, things get tricky fast.  Some of that is managing/updating state- so relying on options like Redux can be a great option, but in this case, I wanted to see how far I can get on my own.  The test app I’m building (event tracker and commenting system) won’t be too complex, so it should be a good learning experience.  Keeping the functionality in one main container component and passing down anything (via props) that needs updating has worked well so far (and leaves good refactoring opportunities down the road).

Enough rambling- the point of this post is not React’s learning curve- it’s actually about how they’re all just JS behind the creepy bird mask and hooded cloak.  Sometimes, lessons learned in Angular can be applied (almost copy/pasted) directly to React.

Example: I have a filter option for events in my React app.  It’s in a sidebar that appears with every route view.  Click an option (current, past, all) and the sidebar events filter by date.  However, I didn’t want this to change the actual route- a user should be able to check out all the options before changing that, so the filter categories aren’t true links (in the React Router ‘Link’ sense)- they just set a context variable (this.filterType) and fire the method.

That last part is important, because React Router’s Link module comes with a nice option for ‘activeClassName’- set it to equal whatever class you want and when that Link is showing, that class is applied to that link.  I wanted the same effect, but my category headers aren’t Links.

Turns out, you can achieve this pretty easily.  I already have the filterType class variable.  I also know you can bind React’s className attribute to the result of a Javascript conditional.  I’ve also done something very similar in an Angular template file.  The code that makes it work in React (inside your element in JSX) is below. This one is on the ‘Current’ category filter button:

className={this.filterType === 'current' ? 'link-active' : ''}

In Angular (2) it might look like:

[ngClass]="{link-active: filterType === 'current'}"

Not exactly identical, but pretty close, and the idea is the same.  And pretty cool!  It really helps expose that it’s JS all the way down, even if it’s wearing a mask and wandering around the party telling people it’s HTML.  At the unmasking ceremony you get to see exactly what you got yourself into.

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!

I’ll have my effects on the side, please

This one’s about side effects.  I’ve been trying to do some reading on functional programming lately.  It seems really cool- though a lot of it is still over my head.  It seems like the fundamental tenet is the elimination of side effects.  A function should do one thing, and do that one thing every time it’s called.  If it adds two numbers together, it does that, then returns the sum.  It doesn’t add them together, drop down a menu item, update the state of your app, and then return the sum.

The idea is great, if a bit lofty for web development, where side effects are sometimes a necessity.  But the underlying principle of avoiding side effects is a good lesson.

So we launched the new website, and it seems fine.  But as with anything this large, there are bugs.  We fix them as they’re noticed, but one we didn’t even consider has to do with the main menu and Angular views.

To view a certain product, you click the link and Angular routes you to a new view.  All well and good.  But all other content from that page also sticks around- some of it not really necessary- and could be confusing.  So a co-worker had the idea to simply hide some sections (with a combination of ng-show and ng-if) when viewing a product route.

Works great- the view pops up quick (no reloads- thanks Angular!) and the non-pertinent info is hidden.  But there’s something we didn’t think of: the main menu.  It’s at the top of the screen- with links to all sections of the page, some of which are now completely unavailable.  Click one of those, and nothing happens.  Probably not a huge issue, but one that should be resolved.

So, I started writing a simple function on the main scope to show a hidden section if that menu item is clicked.  Simple enough.  But yet another side effect crops up: the footer.  It uses a different controller, so now I have to create a service to share state between the footer controller and main controller.

Eventually, I got it working, though services/factories in Angular still give me the run around.  It’s simple enough when they’re just used to provide data, but when you need to change that data, then share it between states, it gets a bit complicated.  Though it was a good day of trying different design patterns.  I finally settled on the ‘private variables’ option: initialize an object with a couple boolean vars in the service, then return the methods used to update and check those variables.

Works like a charm, but it does make the whole functional programming thing look pretty nice.  My last 2 weeks of work have been devoted to fixing issues created by side effects.  Also, on a side note, for the Angular masters out there- is there really a downside to using rootScope?  That was my first solution for sharing state between the footer and main controllers and it worked like a charm.  But everything I’ve read says this is a bad idea (though no one says why), so I spent a few extra hours working out how to do it with services.  Either way seems to work just as well, but I’m sure I’m missing something.

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!

Play nice

The saga of Django-Angular continues!

We finally made a bit of a breakthrough.  I realized that Angular routing can work with Django routing just fine- it just takes a little of massaging both egos.  You see, no one likes to be left out, least of all Django, and that’s where my thinking was falling flat.  I thought we could just have the Angular routes take over, but where would they go?  Django is handling the ‘response’ part of any request in the http chain, so yes- we could set up Angular routes to handle some views, but still had to create those (literally in the views.py file) within Django.

So we added some $routeProvider.when() calls.  Cool trick I also learned- the templateUrl option can receive a function.  So really, we only needed one- pass the function the route params, then grab the current param off that and return it.  This way, we don’t have to set up individual routes for each path- one will do the trick:

when('/:id', {
  templateURL: function(params) {
    return 'path/to/your/file'+params.id;
  }
}

This awesome snippet brought to you by this badass: http://stackoverflow.com/a/15817458

Note that I’m leaving off the ‘.html’ that might go at the end of the return statement- Django doesn’t like when you tell it what type of file to get, it does that all on its own!  It will still work on another framework (or no framework), just add the ‘.html’ to the end of the string.

The final step was to appease Django.  First in urls.py:

url(r'path-start-here/(?P[a-zA-Z0-9_-]+^$', viewnamehere)

And finally, in views.py:

def viewnamehere(request, endpath=None):
  if(path):
    render(return_to_response('yourfolder/'+endpath+'.html', locals())
  return render_to_response('yourfolder/yourdefaultfile.html', locals())

I’m sure there’s something off here- it works, but only with one folder (if I try to make a 2nd url and view for a different folder, Angular never seems to pick it up).  So there’s more work to do, for sure, but it’s very useful for a project that doesn’t require too much deep organization.  It was also neat to learn a bit more about Django views- I didn’t realize you could pass the optional parameter (endpath=None) and have two outcomes for the same view (though, in retrospect, it does seem quite simple!).

Getting Routed

Routing confuses me.  But not always.

The app we’re working on lately combines Django and Angular.  Both great frameworks that function similarly in some ways (injecting templates directly into the html, even using the same curly brackets), but very different in others.  Like routing.

Or maybe it’s just me.  I find Angular (1.x) routing really straightforward to use.  You’ve got your routeProvider, can grab GET parameters off the routeParams object, and just set up your .when() calls.  Although, as a short aside, I did find one gotcha with Angular.  I thought I was being so clever- I wanted to set up a default route using .otherwise() to make a 404 type page for the app.  So if a user goes to a url that doesn’t exist, they get a nice message that they’re lost and a link to a sitemap type screen.  However, the default route will show on first display of the app, so that was kind of tricky.  I didn’t want a 404 to be the first thing people see! So I tried to make a .when(‘/’) route, and have .otherwise point to that.  This is not a good idea.  It created an infinite loop that crashed Chrome (unrecoverable- had to ctrl-alt-delete out of it).  So don’t do that!

But in general, Angular’s routes are really nice to use.  I had (have) more trouble with setting up Django’s routing.  Maybe it’s my (rational) fear of regexes, but the urls.py file reads like Greek to me.  I can get simple routes working- but that’s mainly what I was able to tweak after doing the default Django blog tutorial.  The concepts behind Django routing seem to make sense, it’s just the practice of getting them to work (without spending hours of trial and error) that’s taking quite a bit longer to learn.

But in all, both are great ways of handling the request/response of the web.  Set up one section of routing (or two with Django- you need the views.py as well) and let the framework do the heavy lifting!

Grunt with the Effort

I was tasked to find a good service to concatenate/minify our javascript and css files.  Of course, I’d heard of these words before, but never actually used the techniques.  My other major project involved some very old practices, including inserting php directly into a css file (and rarely, a js file), so minifying would absolutely not work.

But I’d heard of a couple- Gulp and Grunt for example- so I took on the project.  I checked out Grunt first, for that time-honored reason: the alphabet.

And it’s awesome.  It was a little intimidating at first, but after going through the initial setup (pretty easy with npm) and taking a little bit to learn about the two core files (package.json and the gruntfile), I found it to be really friendly to work with.  After all, it’s really just a bunch of javascript, and I like working with that!

The stumbling would come later, when I realized that our new project was built in Angular JS by many different developers.  With no current js or css style guide, I started to run into trouble.  The minifier doesn’t like Angular’s syntax on some things, particularly templateUrl within a directive, but setting the ‘mangle’ config option to false seemed to help.

Minifying was working, but concatenating is still not.  There are errors or unclosed tags somewhere in a directive (not written by me!  I never make mistakes- really boss!).  Somehow, they work in a full sized file, but it does not survive the minification process.  So now it’s time to check each directive, and each template html file to see where we’ve gone astray.  Not looking forward to that.

Speaking of things I’m not looking forward to: we’re trying to push the latest version of the Angular-Django app from our local machine (running the default Django dev server- where it runs perfectly) to the remove dev testing server (where it doesn’t run at all).  This also looks to be an issue with Angular- the templateUrl isn’t getting the right path, which is throwing a very unhelpful error in the console and blocking almost everything from loading.  I know hunting bugs is a major part of the job, but it might be my least favorite.

It has, however, convinced me of the need for a style guide.  It’s not really up to me, but it will be suggested at our next meeting.  There are plenty of good ones out there to emulate (copy).

Defining the Json

There’s a new project in town.  We’re trying to hook up a homepage contact form to an existing Django-driven database via AngularJS (that’s a lot of buzzwords!).  The form has a few required fields, and some more optional fields.  The first couple tests didn’t work- turns out the culprit was the models- the non-required fields didn’t have the blank=True, null=True settings enabled, so the form was getting blocked there.

As an aside- troubleshooting a form submission using Django and Angular can be tricky.  Normally, Django gives you a nice, long error page with what went wrong.  It’s not always easy to decipher, but it always at least points you in the right direction.  But when sending it back and forth via an $http request, it can be more difficult to get the actual issue.  I settled for logging the response.data on the failure callback function to the console- that way I could at least see where in the chain I was going wrong.

So, I changed the models to allow blank entries on those fields that aren’t required.  Boom- no more error message.  Status 200, data being properly sent, good to go!

Not quite- now everything said it was working, but nothing was being saved to the test database.  I tried changing the function within my Angular controller.  I was really proud of my solution originally- to loop through all the form fields dynamically on submission, using a for-in (with the hasOwnProperty check) loop to get all the form ids and values (so if we want to change the form, we don’t have to change the Angular function- it will just get the new fields).  But maybe that was an issue (though it didn’t throw any errors), so I switched and manually grabbed the value of each form field.

Still no luck.  To make a long story short (too late), any field left blank when the form was submitted was being registered as ‘undefined’.  JSON (the format data is transferred in via an $http request) doesn’t like undefined, and was failing whenever it saw that in the object.  The solution was easy- I reinstated the for-in loop and added a check on each item (data is an empty object initialized higher up in the code that would be passed as data in the $http call):

for(var item in form) {
if(form.hasOwnProperty(item) {
data[form[item].id] = form[item].value || 'Info Not Submitted';
}
}

This prevented any undefined values from being submitted via the form, and everything started working.  Next time: I extol the virtues of Django’s built in JSON encoding functions.  They’re really great!