Showing posts with label geolocation. Show all posts
Showing posts with label geolocation. Show all posts

Wednesday, 24 May 2017

Weather App - conclusion

I’ve not really kept up on documenting my progress on this - got distracted with one thing and another. But for continuity, here’s how things ended up:

The app is finished (under some definition of ‘done’); it meets the requirements as laid out and superficially has the right functionality.

Here’s a link

It’s pretty crappy. But TBH I’ve extracted the lessons I need to from the project and I’ve moved on and done better work. I don’t think there’s much value in making this one better, though it’s painfully sloppy!

Here’s my main lessons:

Do

UI requirements first

  • gives structure to the project and is easier and more exciting at the beginning when energy and optimism are high.
  • creating placeholder values starts you thinking about what functional structure is needed
  • slotting real functions into an existing framework is easier than building a framework around functional components
  • adding real functionality to a pretty mockup feels like turning pinnochio into a real boy
  • good looking mock up IS a definition of done, right? right?
  • trying to polish a turd at the end of an exhausting mental process is dispiriting

Use MVC

  • I need structure.
  • Once the UI is mocked up, how is it kept separate from all the other junk I want to layer on top?
  • It just makes sense

Don’t

  • start working on other projects before this one is finished
  • use codepen for work that requires significant coding work
  • … or at least, don’t work directly in codepen. frustrating
  • leave big boring bits of straightforward logic to the end. doing conditionals for the backgrounds and icons was a chore

Conclusion

Pretty basic stuff, but useful to really know it from experience. I applied much better discipline in my next project, for which, see next post.

Tuesday, 2 May 2017

Weather App - code execution

State of Play

I made good progress yesterday - really pleased I started with the presentational aspect and got an adequate level of responsiveness in at an early stage, along with the layout. My codepen got picked for the front page almost as soon as I had these in place - I don’t know if that was a mistake or just because I’d laid it out reasonably well and used decent placeholder styling.

I also think being very systematic about the the presentational components is good practice because you end up with a very modular framework. Because I wasn’t sure exactly what the subsequent implementation would look like, I couldn’t make any assumptions about where and how I needed to manipulate values, so I ended up defining variables for:

  • each DOM element
  • each component value to extract from API object
  • each subcomponent of the composite value to be displayed (eg tempand temp-unit)
  • each weather type before an image is selected

All of which means I have very granular control of how the data will be combined functionally - it just becomes a matter of plugging things together.

Because it was all being done in abstract rather than ad hoc it can be reasonably clearly structured.

So the app has a solid foundation. I struggled for ages to get navigator.geolocation.getCurrentPosition to work, but the lesson there is to read the API. The key for me was this stackoverflow answer:

What you want and what you can have are two different things. Almost everything in Cordova/Phonegap is asynchronous, which means you cannot do var p = navigator.geolocation.getCurrentPosition(onSuccess, onError);. You have to use the onSuccess function to return the value.

If there is no error and you are in onSuccess, this is where your code continues, and will use the position returned. Which means you probably have to refactor your code and/or rethink your workflow.

Once I understood that, I got back on track.

Current Problem

When the page loads all the functions and values get hoisted and I end up with my coordinates variable undefined. I need to figure out how to execute the code in the right order so that the page defers creating the DOM until the ajax request returns, or executes an update function once to insert the values after the page loads.

  • promises?
  • .then statement? (is that the same as a promise?)
  • some sort of chained or bound execution sequence, where the update function is created following the API call>

Log

Not making any progress with that so I turn my attention to some other features until someone arrives whose advice I can ask.

Temp conversion

The temp is given in kelvin, so I apply some conversions I found.

Used a couple of unfamiliar methods - .toFixed(1) so I don’t lose the decimal place (I think I can live without rounding it) and parseFloat because I want it to be a number and not a string like toFixed returns.

That was easy!

Main Issue Update

B came and helped me look at the code and (we think) identify the problem, which is this:

 function getWeather(address) {
      var jhr = new XMLHttpRequest();
      jhr.open("GET", proxyCORS + address, false);
      jhr.send();
      console.log(jhr.status);
      console.log(jhr.response);
      response = jhr.response;
      update();
   } 

jhr the new XMLHttpRequest object has an onLoad property that determines the consequences of the call being answered. At the moment I’m doing nothing with this, so when jhr.send is invoked it does, indeed, send the http request, but then immediately executes the subsequent code without waiting for a response. Looking at it like that, response is undefined because at the time it’s assigned jhr.response is undefined.

I’m going to hack my way through this for the purposes of the project, but I should come back and look at using promises at some point.

Log (resumed)

Long hours and many mis-steps later, I finally got it so the app is updating from the API’s response message. I had some help, too in verying degrees.

The key points are:

  • set an onload method for the https object - it fires automatically on receiving response
  • if successful, pass the object to the update function but not before it’s JSON.parsed
  • make sure the local and global variables are in the right places

I also stopped messing around with functions that convert the temperature on the fly and just put both variants into an object with a toggle function that switches between them.

ToDo

  • background images change in response to weather category
  • improve the UI - two lines for location? flag?
  • weather icon?

There’s an MVP to be had here - tick off the user stories and call it a day.

I”m also tempted to rewrite it as a react app because all a lot of the problems I’ve had have fel like react would solve them: component lifecycles for API requests, state for temperature variants and api data, structural clarity etc.

Hmmm.