Sunday, 28 May 2017

FCC - twitch viewer II

Day 3

I should point out that I’m hardly working flat-out on this! Yesterday I was working on it at the code pod meetup, so my pace has been fairly leisurely. Today I’m grabbing an hour while the family’s out. Have completely lost track of the actual time spent. Maybe do pomodoros?

09:47

I’m probably at the point when I should start on the API, I’m going to revisit my pattern from the wiki viewer and try to complete some kind of call/response. Need to use the FCC workaround, it seems.

Day 4

Day 4 is actually several calendar days later, since I’ve had childcare and family days in between. So my flow is broken a bit and that’s something I need to watch. I can’t help these breaks in focus, but I need to plan for them better, maybe have specific notes to step into, and preferably have something fun and/or straightforward to do on resumption.

Right now I have neither of those things since I’m right at the beginning of a new section (the API) and I’m not clear how to proceed, and don’t have a decent run in terms of time, either. Well, at least I’ll try to get myself set up for next time.

Log

I’m going to generalise my API call/promise pattern into a github gist right now.

done

I’ve copied this into the twitch viewer and added the heroku proxy prefix to bypass CORS issues, and replaced the base twitch API url with the one provided by FCC.

It is returning something that looks like it has the data I need. I just need to parse it out and figure how to incorporate it into the app. Still don’t really get the CORS stuff or how promises are properly used.

Working in github pages.

Now the drill is charged, so I am obliged to resume my DIY chores.

Log

Evening now. Realised the query url I was using has a placeholder for callbacks in it. Took that out and looked again at the FCC workaround page. Looks like I have 3 calls I can make:

  • users
  • channels
  • streams

And I think I’ll have to make different calls at different times to fulfill these user stories.

Right now I’m thinking call one at init to get the avatar and whatnot (the ‘static’ user info) and then calls on the streams for subsequent updates/filter refreshes etc.

Maybe I should curry the basic query function to return variants on the string… but then do I need different ways of dealing with the responses?

need something like:

const userNameArray = ['medrybw', 'freecodecamp', 'femfreq', 'lootbndt', 'spitchell']; 
controller.init () {
    getAllUserData(userNameArray)

},

getAllUserData(array){
    array.forEach(user){
        submitQuery('https://cors-anywhere.herokuapp.com/wind-bow.gomix.me/twitch-api/streams/' + user).then(function(response) {
        localStorage.setItem(user, response));
    }
}

…Well anyway, decided not to use localStorage (yet), but I got this working pretty well!

I have real data from api responses pushing into an array of objects on the data property accounts and the view will render a chunk of HTML from an _js file for each. Current problem is to get view.render to run only when all the data is collected.

Another promise?

Then I need to write the refresh function and get stream-data and then add logic that acts on whether the stream is live or not.

FCC - twitch viewer II

13:00
Day two, and my clarity and resolve is already under assault!

I got a little bogged down into how to display an svg logo (abandoned now), and I find myself dithering over whether to have 2 cumulative filters for online status (on, off, both) or just 3 separate filters.

I guess this is appropriate since it’s part of the UI, which is the phase I’m working in. But at the moment I seem to be mocking up the mockup, still identifying which things I need to include for functional purposes and unsure how they fall out of the API responses.

Writing this helps. I’ll push on with bare-bones component placeholders and not worry about styling for now.

Next I’ll have a pass at the API call and see if I it feels like I’m on the right track.

13:37

Templated the userBox in html. In addition to the container box there are at least three subcomponents. I don’t really want to have to write all those createElement statements in the render function, so for the next 20 minutes I’m going to look into html templates.

13:56
Watched this.
Should I have a go?! Why not!

14:51

OK. This seems to work now:

  • copied the underscore.js dev file into my project folder
  • referenced it in the script
  • used the code under the video in the link above to create my template:
  render() {
    let userHTML = _.template(
      '<div class="userBox">' +
        '<img class="avatar" />' +
        '<div class="userText"><%= userName %></div>' +
        '<img class="statusIcon" />' +
      '</div>'
    );

  let toAppendString = '';

  for (i=0; i < data.accounts.length ; i++) {
  toAppendString += userHTML(data.accounts[i]);
}  document.getElementById('container').insertAdjacentHTML('beforeend', toAppendString);
  }

So, what it does is make a string then iterate over the data object appending variants on the template, then renders the whole block as HTML. Wonder if that’ll cause me problems later? Oh, well, for now it’s happy days!

Apart from using _js, the only new thing here is the insertAdjacentHTML method. I suppose I ought to look into the spec later.

15:20

So, feels pretty good. Major lessons include:

  • don’t be scared of new things (when’ll that sink in?)
  • timeboxing might help me not be scared to try but also not dive too deep on first attempt
  • (spec) have something I’m confident I can be successful at as a back up before trying something dodgy?

Now I’m going to polish up the UI a bit since I’m reasonably confident I can work with what I have so far.

Todo

  • check insertAdjacentHTML spec
  • read the _js source code please
  • figure out, if I’m using _js, I might as well make the most of it so what else can I do with it?

FCC Project - Twitch.tv

Hot on the heels of the Wikipedia viewer, the next exercise is twitch.tv stream.

I’m officially starting this today at 11:00, so I might even log the number of hours I spend on it.

In line with what I’ve learned in the last two projects, I’m going to design the UI first:

UI

  • User Story: I can see whether Free Code Camp is currently streaming on Twitch.tv.
  • User Story: I can click the status output and be sent directly to the Free Code Camp’s Twitch.tv channel.
  • User Story: I will see a placeholder notification if a streamer has closed their Twitch account (or the account never existed). You can verify this works by adding brunofin and comster404 to your array of Twitch streamers
  • Hint: See an example call to Twitch.tv’s JSONP API at http://forum.freecodecamp.com/t/use-the-twitchtv-json-api/19541.

1) Display list of twitch accounts

1.1) filterable by:

  • all
  • online
  • offline

1.2) online user listings should display further details of what they are playing
1.3) listings should include the user’s avatar
1.4) the user account/avatar/whole listing should link straight to the twitch page

That’s probably enough to get going.

Log

11:30 - account set up, couple of users followed
11:50 - some distractions… Plan approach:

1) mock up interface - attempt mobile first?
2) MVC shell
3) API interactions - this is going to be the hardest bit. Get promises working early on, I say.

12:05 - get distracted by thoughts of a whisky app. aaargh

12:19 - have created a directory and a github repo. added skeleton elements. Need to design my components now.

Wednesday, 24 May 2017

Free Code Camp Project - Wikipedia Viewer

OK, I really enjoyed this one. The scope was nicely limited and I felt like I knew enough to chomp through it in a pretty workmanlike way.

The only point I got bogged down was in the construction of the api query, and that’s the real purpose of the exercise, so that’s fine. And even at that I wasn’t too phased by it.

So here’s how things went:

Having done the Design Patterns course on Udacity (well, the first part, anyway!), I was keen to apply the MVC model.

1) I mocked up the main elements of my viewer - title, search field, random button.

2) Made a shell MVC structure, sticking in placeholders for functions I knew I’d need and as they came up

3) Added the functionality to track user input and grab it with a Submit function

4) Figured out how to parse the user input into the API call

5) tinkered with the API until I was getting something back (though not what I wanted just yet!)

6) Worked on a preliminary approach to the render function

7) Figured out how to use a promise to call view.render on API resolve

8) Did more research on the API to get the right query.

9) Added logic to parse the right API results to the render function and styled it

10) worked back over secondary functionality and todo items I’d come up with along the way.

and

There was a fair amount of interplay between steps 4-8, but I tried to be methodical and avoid work that might need to be replaced by a change in other parts of the program.

I used git obsessively for this, making branches for all kinds of trivial stuff that really didn’t need it - but it was an exercise in discipline and avoiding my own errors.

A few times I managed to catch myself on the the master branch, randomly tweaking things in dangerous fashion. When I did I got things back to a stable condition, branched, resolved the matter, merged and deleted.

Here’s the finished result

It’s nothing special, but I think it’s reasonably solid and I’m proud that I didn’t crib code to any significant extent (there’s one thing I think I need to double check).

There’s outstanding issues on my todo, most important of which is adding breakpoints for mobile use, but TBH I’m probably going to do that on future projects intsead.

Be realistic, right?

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.

Starting Weather App

Prep

Started with a Trello board listing user stories.
Broke down each one into as many considerations as necessary at this stage.

Decide ‘weather’ to use React.

Against

  • clearly overkill
  • very little state to manage
  • smallest scale app imaginable!
  • no frequent re-renders
  • overly complex

For

  • extensibility of app
  • better example for portfolio
  • I want to learn React!
  • I’m probably as good with it as vanilla web-dev
  • I want to

Decision

No. I will go for the simplest implementation possible at first. But I will think about how it would work with React, make notes relevant to that conversion, and consider a flashy show-off portfolio version at a later date.

Start

Presentation was my weak point in the quotes project. I plan to get my presentation defined first for this, with the assumption that the logical components will slot into it more easily than trying to design around functionality.

This is also consistent with a react-style approach.

Create a layout on codepen

Make a basic responsive framework by copying the settings from that earlier pen Piotr helped me with.

Basic frame

Uses a full screen solution from Stack Overflow. No idea if it’s ‘good’.

Key to maximise bg image was 100vh as the height of the div to which it was set:

.background {
   height: 100vh ;
   background-image: url('https://static.pexels.com/photos/38928/pexels-photo-38928.jpeg');
   background-size: cover;
}

Add placeholder boxes

Now at the point when I need to add placeholder boxes, values, it’s probably time to investigate the API to see what data I’ll have to play with. At minimum, I need:

-location
- prose description
- icon
- temperature display
- temperature button

temp display and button should be two components composed (keyboard shortcut for change unit as well as button? Two buttons - F and C? How to communicate best via the UI?)

conclude this section

  • Responsive background image is set via CSS and is injected by js. Ready to be acted upon by a function.
  • mobile-first approach stacks the info boxes vertically.
  • text size is responsive to the screen width.
  • values of location, weather and temperature are derived from a dummy JSON object - ready to receive actual API responses.

Start App Logic

I have already separated my values out into (what seems to me) well-defined variables.
I ought to be able to manipulate all the relevant aspects relatively easily once I am able to retrieve real data.

The current challenges are:

  • get the user’s location from their IP address (need to handle errors on this - add manual input via dropdown on fail? react starting to look good!)
  • parse location info and make API call

get location from IP

var x = document.getElementById("demo");

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
    } 
   else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}

function showPosition(position) {
    x.innerHTML = "Latitude: " + position.coords.latitude + 
    "<br>Longitude: " + position.coords.longitude; 
}

END OF DAY 1

Notes & follow-up actions

  • look up the inherit CSS property
  • use class or id for things like app and background? clearly unique elements
  • preferences for unicode display formats