Hoisting usually allows you to declare variables anywhere in your code and they will work- even if you’ve technically used them before that line of declaration. I know- it’s bad practice, but sometimes there’s a slight tradeoff. If I have a bit of code that depends on specific variables, it can be easier to declare them directly above that bit of code (closest to the actual use). Of course, they’re ‘hoisted’ up to the top of the enclosing function to be initialized, so it’s really just a readability trick (though the block scoping ‘let’ keyword should clear up some of this confusion with es6).
So I try to keep my old ‘var’ declarations at the top of each function, but sometimes fail. And that can lead to bad habits- like forgetting to check order in other aspects of my code. For example: we had to go back to our Angular 1.5 project to add some custom validation to a contact form. It was just using the default HTML5 ‘required’ validations- useful, but not really in line with the rest of the page’s look n feel.
So, we added some checks and used the cool ng-messages module to show some custom notices. Worked great- mostly. However, the form allows the user to reset after submission- in case they want to submit another question. For some reason, the form would not clear. More specifically, the scope was never removing the original submission object.
We tried everything: resetting each $valid/$invalid attribute, setting the ‘passedValues’ object that was storing the submitted values to an empty object after submit, setting it to ‘null’, resetting the form using a plain old document.getElementById(‘contact-form-id’).reset() call- none of it worked. The screen would clear out old values, but the scope would not reset- the initially submitted values were still there. We could tell because at one point, we just started logging everything to the console (there are a lot of properties on a submitted Angular form!).
Long story short (too late), the issue was order of operations. We had the call to reset the actual html form after calling ‘setPristine’ on the angular model. So, it looks like the values were still technically stored in the form object when the reset() method was called on the form, and they (the original values) were re-inserted right back in, and then cleared from display.
Or maybe it’s something completely different, but that’s the best explanation I can come up with because as soon as we moved the form.reset() declaration to the top of the $scope.reset function, everything worked great. Maybe we are correct- the order of operations was wrong. Or maybe the form Gods took pity on us after we burned way too much time trying to figure it out and fixed the reset for us. Either way, it works now!