Working Remotely

In my current position, I work remotely with a team of four other full-time employees. Three of us live in Pittsburgh (two are developers) and two live on the West Coast — if you consider Reno the West Coast. Anyway, our work flow is to meet (usually) once a day at 12:00 PM for “standup” using Zoom. That time is devoted to people sharing their Asana screens and talking about what they’ve done, what they are doing next, and if anything is blocking them. It is considered ideal for those meetings to take less than fifteen minutes. Once a week, on Wednesdays, we “meet” for an hour to review and plan the “sprint” for the next week. Most of that time seems to be devoted to the CEO and CTO arguing with each other. In between, we/ they use Slack for any quick questions or jump on a Google Hangout to go more into depth into an issue or concern.

The three other developers on the team are fairly experienced, and working remotely is a great way for them to have flexible schedules. Also, they are coming from another company where they worked together and in order for the three of them to continue to work together, they have to work remotely, with two of them being of an age and situation where picking up and moving is out of the question. After I accepted this position, I was offered a full-time position at a local company that would be about a 45 minute average drive from my house. When I thought about all I have to do as a mother of three with my husband gone most of the time traveling for work, I knew that I would probably not (ever?) be able to work at a company five days a week on site at a starting salary.

Unfortunately, it has not been optimal for me to work remotely for several reasons. One of those reasons has to do with getting blocked on very simple questions and tasks and thus spending a lot of time trying to figure things out. That is definitely a problem.

I was pointedly and repeatedly questioned/ scolded yesterday for the amount of time I spent working that was not “billable” time. We use Harvest to keep track of our time spent. Ideally, almost all of that time is on tasks for the company that hired us to build the site and are detailed in tickets in Asana which are created directly from the bid. I billed for two hours last week — two points, two tickets — but clocked 48 hours in Harvest on “education.” I included notes for each education task. That “education” was me trying things and looking things up and trying things and looking things up again in order to make the code do what it was supposed to do. I detailed and clocked all the hours spent because I wanted the others to know that I was working hard and wasn’t blowing off the work. My choice to only bill for two hours goes back to the response I got when I asked how to bill for my first task in Asana. I told the CTO that I had spent at least eight hours (it was probably even  more than that) and he met that admission with astonishment and reluctantly told me to bill for two hours for the ticket/ task.

Aside from feeling terrible about how long it is taking me to do what to others are simple things, I clearly got the message that a one point task should be billed for two hours at the very most.

A lot of my slowness has to do with my newness to certain languages and uses of the languages. But another major cause of slowness is my lack of overall knowledge relating to certain little tricks or syntax. Sometimes I happen on answers to those questions serendipitously and quickly. More often though, there have been so many times in my brief career as a  developer when a more experienced developer has told me something in a short sentence that would have saved me literally hours of time. I don’t know how others deal with these problems. I don’t know if I am stupider than most or more forgetful or going about things all wrong. But that is my experience.

Two examples from the past two days might illustrate what I am talking about. In one case, we are now using Redux and Thunk in a React front end for a web app. I have not used either before and was a little overwhelmed with the confusing practices. I followed a tutorial, but it did not use Thunk, so that particular file — the action creator that uses Thunk — was fairly confusing to me. The stupidest little thing was preventing me from really understanding what was happening (and thus being able to make modifications to do what I needed to do), and it has to do with ES6 syntax. When you are writing an anonymous function, you can eliminate the parentheses if only one argument is passed in.

So when I saw this function:

export function importDelete(id) {
return dispatch => {
deleteImport(id)
.then(response => {
dispatch(importDeleteAction(response.data.import.id))
}).catch(err => console.warn(`import deletion failed: ${err}`))
}
}

All I saw was gobbledy gook at the top. I could not figure out why two dispatches were being called!? What was the first one even doing? Now I understand and can write this function passing two arguments to the anonymous function:

export function exportCreate() {
return (dispatch, getState) => {
const state = getState()
exportPolicies(state.startDate, state.endDate)
.then(postResponse => {
const response = postResponse.response
dispatch(exportCreateAction(response))
}).catch(err => console.warn(`export create failed: ${err}`))
}
}

The other stupid thing that threw me off that someone corrected with one word has to do with styling with Bootstrap. Styling things is absolutely not my forte. A UI element I was making that was meant to be an input group where someone could put in a start date and end date and then hit a button to send an API call just was not lining up and was looking very ugly. I tried using inspect and looking at padding, margins, alignment, justification, you name it. The next day, after giving up, I asked for help. The senior front end developer suggested just putting the elements inside a row. Ta da! Now it all lined up with the content that followed and looked so much better.

Because I feel so incompetent I am reluctant to ask what seem to be stupid questions. In fact I was told two days ago that I “often ask questions I already know the answer to.” I would disagree, and it certainly makes me even more reluctant to ask questions. Not working side by side with people and developing a level of comfort and a rapport with them has made it very hard for an old, new developer to learn and grow at a reasonable rate. So, I say to you if you are still reading, if you are a new developer, try not to work remotely, and put it in a row.

 

 

 

Advertisements

Working Hard vs. Working Smart

Should I be grateful to be praised for working hard?

My mentor yesterday again stressed the importance of TDD. You might wonder how these two sentences are related. I will get to that; I promise.

Why TDD? It can help you design your code in a smart way. If you need to bring in all sorts of stubs and mocks of other functions and objects to run a test, then you are probably not creating code the right way; it is too modular. He says the test is the first user of the code, and says that it allows you to see what is involved in that code usage. I have not really been using it. He was saying this in reference to code that I wrote and how awful it was.

Of course I have not been using TDD. Maybe I’ll start. We will see. I haven’t because I usually spend so long on tests. Yesterday I spent about four and a half hours trying to get one test to pass. That has been a recent pattern for me, spending hours and hours trying to get tests to pass.

In the current project we are working on, we are using Rails and Rspec in the back end. Like with most things in code, I am trying to learn by copying existing examples in the code base and using Google and/ or documentation to figure out what to do. As “everyone” says, once you learn the coding concepts, it is just syntax. I could not disagree more. Because of that, none of my superior or colleagues or whatever ever take the time to teach syntax. I am expected to figure it all out myself.

Luckily, with Rspec, there are plenty of SO opinions and ideas. Rails has been used for years and years, and Rspec along with it. The docs from Rspec itself are not at all helpful though. I am always lead to the Relish site and that was last updated two years ago and all it does is confuse me.

Here is one example of the trouble I had and what I eventually discovered.

I created a get endpoint in a controller that is where users will go to when they get an email to activate their account (or update their email). This endpoint does not have any of it’s own resources. However, it does modify the user resource by setting an activated_at in one action and resetting the email in a verify action and then the new version of the user is returned in the JSON. In the controller test, I was able to copy other patterns in existing tests to check for valid JSON, and that passed perfectly.

Then, with the CTO of the project who has been working in Rails for ten years, said we need to check if the user was updated. He is also serving as an instructor for me, mostly in the Rails part of the project. Unfortunately, a stupid mistake on my part and lack of attention on his part, led to a test that passed because it was not testing the right thing. I accidentally checked if the updated_at property on User was not nil instead of the activated_at. The test passed and the CTO hung up.

Here was the test:

context 'should respond by returning a user and updated_at in json if token is found' do
  subject { get :activate, params: @valid_params }
    it { expect(json.keys).to eq(['user']) }
    it { expect(json['user']['activatedAt']).to_not be_nil }
    it { expect(@test_user.updated_at).to_not be_nil }
end

It was only later I realized the mistake, and when I changed the test to check the activated_at property, I could not get anywhere after flailing around for quite some time. Of course I tried to rewrite the code in the the controller, thinking perhaps it was the actual code that was causing the problem. I really doubted it though. Then, when I was asked about the status of the pull request by the other two people on the project, I explained the problem I was having. The tests were not showing that the user was being updated. One suggested I try to reload the instance of the user that I was using in the test. @test_user.reload.

The reload did not work, but it lead me toward an answer. I got the response from the test that it could not perform reload on nil. Aha. This was a clue. Why was the @test_user nil? First I tried a different way to create a user instead of using the test user created in a helper file. No luck. Imagine hours passing. Of course it takes about five minutes to run each of the the tests, but a lot of that time is me not making decisions that make sense. binding.pry was not a super help because it showed that there was a @test_user. It was the old version of the @test_user, though, and didn’t show any updates.

Eventually, I realized through some random Googling and one of those ah-ha moments that the problem was how I was writing the test. I had been using the language of the test without understanding at all what it was doing. By copying and pasting and not really investigating, of course it would take me hours and hours to write a passing test. Even though knew from the start that the “it” in the test related to the “subject,”  I didn’t really think too hard about that subject and what it was or wasn’t doing.  Here is the relish docs explanation of “subject”:

“Use subject in the group scope to explicitly define the value that is
returned by the subject method in the example scope.

Note that while the examples below demonstrate how subject can be used as a
user-facing concept, we recommend that you reserve it for support of custom
matchers and/or extension libraries that hide its use from examples.”

I still don’t understand what that means. Do you? Eventually, what I landed on is that the subject should not have been the get request. The subject should have been the user.

Now the test looks like this:

context "should update the user object's activated at to the current time" do
  subject(:active_user) { User.find_by(perishable_token: @user.perishable_token)}
    before { get :activate, params: @valid_params }
    it { expect(active_user.activated_at).to_not be_nil }
end

And it passed!

You’d think I’d have learned. Then yesterday I spent about 4.5 hours not understanding why a test wasn’t passing without thinking about what exactly the test was testing even though the words, “it doesn’t test side effects” should have made me realize it! I kept modifying the code and the tests still didn’t pass.

Perhaps now you  realize why I have not been practicing TDD. If I have so much trouble writing tests, how can I possibly ever use those to help write code? I have not been able to work smart enough to work smartly. I have no solutions. Only mistakes. If there were a good way to learn more about how these tests work, I guess that would be a good start.

Lessons from Working on a Small Team

Cargo Cult Programing

Since October I have had the great pleasure of working with a brilliant man who has served as a mentor in both programming and working in the development world. Yesterday he told me a little about what he thinks is “cargo culting.” I had never heard the term, but after having one explanation and then reading about it, I agree with him that it’s such a regular phenomenon, there really doesn’t seem to be any reason to have a specific term for it.

As was told to me, but turns out not actually to be true, cargo culting, in case you are not familiar with the term, refers to some alleged behavior discovered by an alleged anthropologist among some Pacific Islanders during World War II.  Planes would crash sometimes and crates of supplies would wash up on shore of these islands. Imagine the delight of these islanders to find boxes full of bad tasting chocolate and cartons of cigarettes (or whatever there was). So, in response, the islanders would take to performing repeated rituals that related to what they were doing when the crates washed ashore. So, if they had been talking to a certain person or had eaten something particular, or had performed a certain task, they would then do that thing as a ritual in the hope that it would send more delightful supplies to their shore.

Cargo cult behavior, according to Wikipedia, anyway, is a lot more complex then that. But the point is, to quote Wikipedia, the term “cargo cult” has been used metaphorically to describe an attempt to recreate successful outcomes by replicating circumstances associated with those outcomes. It is particularly used in the computing world to describe inclusion of behavior for no real reason.

I thought about this term last night when we had our mandatory meeting with the Rabbi before my son’s upcoming Bar Mitzvah. She talked about why old Torah scrolls that have holes in them and can be no longer used are still kept in the arc (harom a kodesh sp?). She said it’s because when Moses went up to get the ten commandments from God and smashed the pieces, the new ten commandment tablets and the old, smashed, broken tablet of commandments were both included in the ark. That makes you realize that basically all of human behavior is some form of cargo culting.

So, back to programming. Now I am working with a few other experienced programmers, which is a great opportunity for me. But, there is a lot of tension on the team. On the one hand, there are the people who repeat over and over, “this is how we did it at company x for years and it always worked out well,” and on the other hand you have my mentor (see beginning of this post) who is struggling to be productive in an environment that doesn’t make sense to him. And then there is the code base, copied over from projects done on the past. And there is me, caught in the middle.

In a future post, I will go into more detail about the environment and work flow, code base, etc, but it has definitely been a learning experience working on an experienced software development team for the first time. There are too many things to write about, and I found I needed to get started again.

Dealing With XML

Until recently, I have only been dealing with API data that is in JSON (JavaScript Object Notation – pronounced like the name Jason) format. JSON looks like

[{"replayEventTypes[{"id":5,"name":"movies","displayName":"Watch"}],
"id":70,
"title":"Notification Testing I",
"date":"2017-05 26T00:00:00",
"startTime":"08:20",
"endTime":"20:00",
"description":"Testing to see if notifications work on IOS",
"extendedDescription":null,
"location":"Not Important",
"image":null}

It could not be easier to access various levels of the object by using the dot notation. To get the values of the properties inside your html, you just reference the property on the object by object-name.property. So, for example, <h1>event.endTime</h1>.

Recently, I had to process an XML API, and, not surprisingly access to the various properties is different than with JSON. XML stands for eXtensible Markup Language. It is similar to HTML except different. Its purpose is to transport data over the web (as opposed to being used for display as HTML is). I was accessing the API in order to allow someone doing data entry to look up an Arcade Game and populate fields related to that game with the values of properties from that API.

Here’s what a “real” example of XML looks like:

<Game> 
<id>2</id>
<GameTitle>Crysis</GameTitle> 
<Platform>PC</Platform>
<ReleaseDate>11/13/2007</ReleaseDate> 
<Overview>From the makers of Far Cry, Crysis offers FPS fans the best-looking, most highly-evolving gameplay, requiring the player to use adaptive tactics and total customization of weapons and armor to survive in dynamic, hostile environments including Zero-G. Earth, 2019. </Overview>
<ESRB>M - Mature</ESRB> <Genres><genre>Shooter</genre></Genres>
<Players>4+</Players>
<Co-op>No</Co-op>

Here is my function as written in the script section of a “create” View file in .NET/ MVC project.

 function fill_form(id) {
            $('#games-by-id').html('');
            $.ajax({
                url: 'http://cors-anywhere.herokuapp.com/http://thegamesdb.net/api/GetGame.php?id=' + id,
                type: 'GET',
                dataType: 'xml',
                success: function (data) {
                    var gameTitle = $(data).find('GameTitle').text(),
                        overview = $(data).find('Overview').text(),
                        releaseDate = $(data).find('ReleaseDate').text(),
                        developer = $(data).find('Developer').text(),
                        genre = $(data).find('genre').text(),
                        players = $(data).find('Players').text();
                    var tempReleaseDate = new Date(releaseDate);
                    var releaseYear = tempReleaseDate.getFullYear();
                    $('#GameTitle').val(gameTitle);
                    $('#Overview').val(overview);
                    $('#ReleaseDate').val(releaseYear);
                    $('#Developer').val(developer);
                    $('#Genre').val(genre);
                    $('#Players').val(players);
                },
                error: function (error) {
                    console.log(error);
                }
            })
        }

So, as you can see, using JQuery and an AJAX request, you need to pass in XML as the data type and pass that data or xml or whatever into your callback function. Then you need to “find” each XML tag in the “data” (or xml or whatever), assign it a variable, and then put that variable into the HTML, which I did using the ids on the attributes.

To load what I would consider an array of XML objects, you can simply look at “each” of them. Good old jQuery. If you don’t have one of the new libraries or frameworks, it sure beats Vanilla JavaScript. For example,

 success: function (data) {
                    $('Game', data).each(function () {
                        var id = $(this).find('id').text(),
                         gameTitle = $(this).find('GameTitle').text(),
                         releaseDate = $(this).find('ReleaseDate').text(),
                         platform = $(this).find('Platform').text();
                        $('#games-by-id').append('<li class="list-group-item"
id="game' + id + '"><span id="catspan' + id + '"></span>' 
+ gameTitle + '</br>' + releaseDate + ' ' + platform + '</li>');
                        $('#game' + id).click(function () { fill_form(id); });
                    })
                }, 

You may have also noticed that I need to make a CORS request here. I will have to address that in another blog post once I figure out how to run my own proxy server.

I read a lot of different posts with lots of different ways to access XML, including from the JQuery documentation, but this is the way that is working for me.

Refactored Push Notifications

In my last post, I described how we set up a local React Native Push Notification to run at a scheduled time. The push notification was configured on the App State Change — background to active and vice versa. By sending an id (on Android) the notification was configured once and sent at the correct time, but only if the user had changed the state of the App. In iOS, there is no ID parameter (as such — I will get to that later), so if a user changed the state (opened the app, put the app in the background) multiple times, the push notification would fire multiple times.

I got to thinking about it and decided on a better way to configure the notification. I was hung up on the idea of an event listener. In React, you really have to either have an event listener or a lifecycle event to change/ update/ set the state. I was pretty sure we did not want to configure the notifications with a button push. Except, we actually did.

The push notifications are for events that are favorited by the users. So, I did a Homer forehead slap (“doh”) and realized we could just configure the notifications on the button push to add the event to the favorites array. And, even better, I realized if someone unfavorited the event, we could now remove that notification.

Cray then figured out that for iOS, we can send in a userInfo object and send an id in as a property on that object; that way there is an id to add and remove on iOS for the push notification. And, we can still use the id string property for Android.

Now the push controller looks like this:

import React, {Component} from 'react';
import PushNotification from 'react-native-push-notification';

export default class PushController extends Component {
    ComponentDidMount() {
      PushNotification.configure({
      onNotification: function(notification) {
         console.log('NOTIFICATION:', notification);
         console.log('User Info:', userInfo);
      }
    });
  }

    render() {
      return null;
  }
}

In a separate file, we have this function call:


handleFavoriteButtonPress(item){

    if (item.isFavorite){

            this.props.removeFavorite(item.id);
          //  Alert.alert('Item has been removed from your schedule');
          let id = (item.id).toString();
          PushNotification.cancelLocalNotifications({
            id: id, //removes local notification when item has been unfavorited
          });
        }
          
          else {
            this.props.addFavorite(item.id);
            if(this.props.favorites.length =10 ? "-"+(favoriteDate.getMonth()+1) : "-0"+(favoriteDate.getMonth()+1);
            let favoriteDay  = (favoriteDate.getDate()+1) >=10 ? "-"+(favoriteDate.getDate()+1) : "-0"+(favoriteDate.getDate()+1);
            let fifteenMinutesUntil = new Date ( favoriteDate.getFullYear()+favoriteMonth+favoriteDay+"T"+item.startTime+ "-"+"03:45");
          
            let id = (item.id).toString(); 
            if( fifteenMinutesUntil >= Date.now()){
              PushNotification.localNotificationSchedule({
              id: id, //for Android
              userInfo: {id: id}, //for iOS
              message: item.title + ' will begin in 15 minutes',
              date: new Date(fifteenMinutesUntil),
           });} 
          }
    }

One thing you should know is that even to send local push notifications, you will need to get the permission from Apple to do so.

As quoted from their docs

For a provider to communicate with APNs, it must employ a valid authentication key certificate (for token-based connection trust) or SSL certificate (for certificate-based connection trust). You obtain either of these certificates from your online developer account, as explained in “Configure push notifications” in Xcode Help. To choose between the two certificate types, read Provider-to-APNs Connection Trust. Whichever certificate type you choose, provider connection trust is prerequisite to a provider sending push notification requests to APNs.

Hope this was helpful.

React Native Push Notifications

See Refactored Push Notifications to get the update. Hey, I said I make mistakes, right?

The most recent feature we have been charged to add to the Replay FX application for the Replay FX convention this summer is push notifications. In the app, convention goers are able to save favorite events locally so they can have their own tailored schedule. We wanted a push notification for them that would let them know when an event they had ‘favorited’ was coming up in fifteen minutes.

We chose the package “react-native-push-notification,” so that we could configure local notifications on both IOS and Android. I watched this helpful video to get started. There are several files to change in Android, and you can easily follow along with the video or use the docs. I did not work on the IOS side, but my colleague Cray configured that in XCode. He had used something similar when he did a code test building a chatbot.

So, we started with a separate file that has State. It has to have “state” because it needs to be updated based on time and the current app state. Cray first had a notification sending based on intervals just as in the video. To render the notification, he imported the component to the item piece of our list view and included it inside the view like this:

Screen Shot 2017-04-28 at 1.52.13 PM

Now that he had set up where and how the PushController component renders, we needed to fine tune the PushController file. Of course, import the file at the top.
import PushNotification from 'react-native-push-notification';


The following code in some kind of form needs to exist to configure the push notifications. Of course, you do not need to console.log but can do all kinds of other things with the notification object upon callback.

componentDidMount() {
  AppState.addEventListener('change', this.backgroundNotification);
    PushNotification.configure({
      onNotification: function(notification) {
         console.log('NOTIFICATION:', notification);         
      },
    });

I wanted to be able to write the code without the event listener because I feel like it just causes trouble, but the package to configure the push notifications does not seem to function without it. The only argument that I could find to pass into the event listener was “change” which is a little annoying. What if the user of the phone does not “change” anything? For example, they could have the app open, favorite an event, and not close the app or put it in the background. In that case, the notification will never fire.

I created a second listener to add to this function to render when we have an in-app notification. And, of course, we remove the listener on “componentWillUnmount.”

The functions are called on “change” — opening the app or putting the app into the background and when the function is called we have a bunch of “if” statements. The code that follows is the function that is for the background notifications. I had to create a different function to run if the appState is “active.” I tried to do an “or/||” statement and just have one function, but it did not work. The app would just crash with the “or.”


backgroundNotification(appState) {
      if (appState=='background') {
      if (this.props.item.isFavorite) {
        let favoriteDate = new Date(this.props.item.date);
        let id = (this.props.item.id).toString();

The above code, gets the date of the favorited items so that we can create a variable that has “state” to represent the date and time of 15 minutes before the event.

The code to create that variable is ugly, but it works, and I don’t know of a better way. Dates and times are very tricky in JavaScript.


this.setState({fifteenMinutesUntil: new Date(
          favoriteDate.getFullYear() +"-0"+ (favoriteDate.getMonth()+1)+"-"+(favoriteDate.getDate()+1)+"T"+this.props.item.startTime+ "-"+"03:45"
          )});

We needed to have a Platform.OS “if” statement to render the date correctly In Android, I needed to add +1 to the getDate(). For IOS, the +1 only needs to be added to the getMonth(), which is also true in Android.

Once we have that variable, we can create a notification to fire at the appropriate time. We had some trouble with notifications firing immediately if the event time had passed, so Cray created the “if” statement at the beginning of the code below to go along with the configuration of the notification.

We had to pass the id or the PushNotification.configure would create a completely new notification object each time there was an app change. In that situation, when I did not pass a specific id, and I changed the state of the app, many, many notifications would fire. By passing the id — by the way, it has to be a string — we only create one notification object and only one notification fires.

The way the notification works “under the hood” is by adding .getTime() to the date and returning the milliseconds. The getTime() function did not work if we did not create a new date here. As it is, the notification fires once at the date and time passed to date.

One little problem that I have not figured out is that when I click on the notification in the emulator it automatically opens the app. I don’t know if there will be a dismiss “x” on the screen of people with real phones. I hope so.


if(this.state.fifteenMinutesUntil >= Date.now()){
           PushNotification.localNotificationSchedule({	
            id: id,	      
            message: this.props.item.title + ' will begin in 15 minutes',
            date: new Date(this.state.fifteenMinutesUntil), 

It took me several days and lots of console.logging but it works pretty well now on the simulators. I can’t wait to see how it builds this evening in our beta. There was very little help out there — only the one video, no StackOverflows, and nothing in the docs — to work for our specific situation. I hope that this post helps you figure out local scheduled push notifications.

And, I figured it out some more important things and rewrote the code after this. See Refactored Push Notifications to get the update. Learning from mistakes, just as promised.

React Native EMFILE Error

So yesterday I was preparing to add a feature to the mobile app we created for the Replay FX convention. We need to add local push notifications. There have been two of us working on this app since our Academy PGH bootcamp ended back in December. To make things simple, my coworker, Cray, has been developing and testing using an iPhone simulator and XCode and I have been using an Android simulator and Android Studio, even though we both have Macs and iPhones.

He had a chance to get back to coding for the first time after his first child was born two weeks ago and got a basic version up and running on his ios simulator. Using git I merged his code into mine and then did a “yarn install” to get the package we are using — “react-native-push-notifications.” I am giving you all of this background because I am still not sure what caused the problem I ended up having, so I am hoping this exposition might solve the mystery later, although it could be a red herring. At that point, a message in my terminal indicated that I should update my version of Yarn using the command they gave, which I did. Perhaps because I installed a new Yarn version I caused some change in one of my dependencies which caused things to break later? I don’t know. . .

At first, the app crashed because my coworker had added new Android “drawables” for our splash screen into a file (called “ApeGeneratedAssets”) outside of the android file. It was so great that he created that splash screen and added those android versions, but they were in the wrong place as far as I could tell. I had not set the layout file to read from there (plus the file names were all a bit wacky). He used Ape Tools to generate the different versions of the image, which seems like a handy method. So I moved those over into the “res” file and renamed them. I’m not sure if this will come back to haunt me later.

Anyway. . . the message which appeared all in glorious red on the emulator was “Could not get BatchedBridge, make sure your bundle is packaged correctly.” In my terminal, the message was “Error watching file for changes: EMFILE {“code”:”EMFILE”,”errno”:”EMFILE”,”syscall”:”Error watching file for changes:”,”filename”:null}”. In Android Studio, the only thing I could find in debugging the project was a seemingly random message from the android/app/build.gradle related to this line right at the top: “import com.android.build.OutputFile” saying “cannot resolve symbol build.”

Googling that message lead me here. So, first, I tried to clear the cache in Android Studio by going to File > Invalidate Caches / Restart as explained in the Stack Overflow post. That did not change a thing.

So, next, after Googling about the BatchedBridge and finding many answers to run “react-native start” (in the terminal) instead of my usual “react-native run-android” I did that, and it changed absolutely nothing. I next Googled about the EMFILE and got this explanation from the React Native GitHub “issues” page. It is explained that the build fails because there is a limit (in the new OS version of Sierra) in the number of files that can be opened. This made sense as a cause of the problem to me as I had added an additional Node module plus all of the big image files. So, I ran “launchctl limit maxfile” and sure enough I found my limit was 256. I ran “sudo launchctl limit maxfiles 2048 unlimited” to change that file limit. I followed the next commands to uninstall the react-native cli and reinstall it and then to update brew and install watchman. And then, tada! It worked. Only 2 hours and 15 minutes later. Now I just have to write the code to make the Push Notifications do what they are supposed to.

CSS and Caching

My original intent for keeping a blog was to help me remember solutions to problems in programming/ coding that I encountered. Because I am learning so much every day, I have had the problem in the past where I have figured out how to do something and then the next time — maybe a week later, or a month later — when that problem came up again, I had forgotten my original solution. I wanted to keep a blog so that I would have a place to record that solution for myself and for anyone who might need it. I wanted to write brief, fact and experience-based methods for solving problems.

So, despite the type of entries I have as my first two posts, what follows is the type of blog post I actually had in mind.

Yesterday I was working on a PC using Visual Studio 2015 to modify a version of Trello (I called it Trillo – clever, eh?) I created during my bootcamp to help me learn dotnet’s MVC. I decided that I wanted to change the colors of my todo cards, so I changed the colors in the Site.css file. But, to my surprise and frustration, every time I tried to view those changes by hitting “play” in VS (using Chrome), they just did not take. I tried reloading, closing and opening Visual Studio, “playing” by using the “Build Solution” menu, checking the save path, saving the .css in a different way (without changing its name), changing the way the .css was being loaded — by including it specifically by name — and nothing worked. When I looked in the Inspector, I had noticed that the source file was an old version of the site.css and it had a yellow triangle with an exclamation point in it which when hovered over said that “changes to the source file were not kept” or something like that.

So, as I should have done an hour previous, I Googled. I have had trouble Googling for MVC solutions in the past because I am dealing with a specific version of MVC, ASP.net, Entity Framework, and Visual Studio, and it is hard to find the precise combination necessary. In this case, there were no shortage of answers. It seems to be a common problem for sure. Chrome is caching the .css files. The easiest solution I found was to open the Inspector, open the source file for the .css, and while it is open, hit CTRL/ F5. This worked immediately to reload the .css file so that the current file was reflected in my local version. Then, when I made additional changes to the .css, I had to do the same procedure.

Looking at the solution in Stack Overflow,  I came across another helpful tip. In the Chrome Inspector click on the three dots menu (on the top right) to open up the Developer Tools. Then click on “Settings.” In there, check the box: “Disable cache (while DevTools is open).” Other solutions have you changing your code to always have you reload the cache. That does not seem that it would be helpful once your site is live, but you could use it while you are developing. If neither of those fixes work for you, please see the original Stack Overflow question I found. There were many, many solutions offered. The two above helped me, but you never know what might help you. By the way, last night I had a dream (nightmare?) that Stack Overflow had been attacked too many times and it had to be taken down. What a relief when I woke up from that one. . .

Steel City Codefest 2017

Last night Steel City Codefest wrapped up at the Ace Hotel in East Liberty. This was the fifth year of the Codefest, and it seems to be a well-established opportunity for developers to take on challenges and create some very cool products for groups who really need them. There were 95 coders who participated this year. My bootcamp, Academy Pittsburgh, sent many, many participants from Session 3, the session that is currently attending the bootcamp. They are on their seventh week of learning and were just introduced to HTML and CSS this past Monday. There were five of us from Session 2 participating and we were divided into two of the three Academy PGH teams to work with the Session 3 folks.

I was away for the kick off and was able to join a team on Monday, when I returned. The group was aiding a nonprofit called the Pediatric Palliative Care Coalition. The app the organization was looking for was one which would allow parents and caregivers for medically fragile children a place to manage all of their many appointments, medications, hospital stays, health checks, etc. Currently, PPCC is offering parents a binder filled with pages for them to write this information. An app makes so much sense as a way to help these parents. It would be easier to organize and search. It could be shared among family members who could be updated in real time about events. It would be more likely to be used and referenced and less likely to be lost. I was really excited to be able to use my new found coding skills to help an organization like this. Frankly, that could be my dream job.

Anyway, life does not always work out as we hope.

The team had met a lot over the weekend and had come a long way with wireframing. They had many professional graphic designers in the group who had come up with beautiful pages and a sensible UI. Someone in the group was very organized and had created a Trello bulletin board of tasks and lots of documents and files pertaining to needs. It seemed like a smart, talented, and organized team. I was very excited to attend the first build night on Monday evening at Google to meet the team and start to build actual pages with code and make them have the potential to hold data.

Our teacher explained to me that he hoped I could make the front end work and he would handle the back end, and I would use that API. This sounded fine to me. We had previously done something similar with an app for Replay FX, something I will probably write about another time. So, I decided I would use VueJS and the Quasar boilerplate/ UI component library. I had used it before and thought it was very easy to learn. I got some help from Ben from Uber, who was assigned to Academy Pittsburgh, to redo our Github repo and help me make some decisions. Ben was awesome, by the way. He seemed frighteningly young, but good skin can do that. He was knowledgeable, patient, helpful, and quick to catch on. He didn’t know anything about Vue, but helped me make the decision to use it when I wasn’t sure if that was the best choice.

Now that our Github repo was set up, our team moved to a room with a projector so I could walk them through creation of a page. I had high hopes that I could set them each up with a page and they could use them as components — create data and process it in the HTML and include CSS at the bottom of the page and then we could integrate them. That didn’t even begin to happen that night. Maybe it was because it was 82 degrees in the area we were working. We were told the temperature could not be adjusted. And the lights kept turning off. I guess Google really does try to encourage their employees to go home after a certain time. Maybe because of that or because they had not had a lot of experience working in Git or because of some other reason that I don’t know we barely got through them cloning from Github and then it was 11:00. It’s all a blur now. No problem, right? We still had several days.

The next day, Tuesday, my Session 2 partner (henceforth, Partner) and I arrived at Academy Pittsburgh ready to work. I set myself up in Chromecast and was ready to show the group VueJS and explain how to add components. Unfortunately, I was having a little trouble with Stylist, the type of CSS Quasar uses, and while I was fiddling with that, the group fell to talking. I think I set them off in the wrong direction. Then, when I was ready to go and starting to show them what to do and how Vue works, after about one minute, one of the group members was casting from his computer to show his HTML. I really don’t remember why. I do know that the reason made no sense and did not help anyone begin to make pages that worked.

That distraction devolved into an argument that continued for about 2-3 hours. Partner and I could not get the group’s attention back. I believe they were arguing about design and who created what and which image should be used and other such things. These are not areas that interest me at all so I don’t recall exactly what the problem was. I just wanted to get started making the thing work.

At this point, I realized we had the problem on our hands that I explained in the first blog post. The team was so set on making a perfect and comprehensive app, that they probably would never build anything. They didn’t just want a car, they wanted a flying, driverless car. Meanwhile, they didn’t even have a wheel and had only drawings of the car. They were arguing about what kind of music would be playing and what color the lights would flash instead of thinking about what they could reasonably build with little experience and three days. I was not capable of correcting their path. I am not sure what I could have done differently.  I wish I had been able to convince them that they were on the wrong track. A combination of certain personalities and their inexperience were too much for me to take on.

After several hours, our teacher encouraged us not to use a front end framework at all and just to code in CSS and HTML, and I would try to add functionality with Javascript and Jquery. Partner took over the teaching and with me cracking the whip, she was able to explain more about CSS and classes and ids and was able to finally get them started. Many of them were very eager to begin writing code. I walked around and tried to help those who struggled and then it was time to go.

Wednesday night we met at Maya Design, a beautiful place to work. If you have the chance, you should really get a tour. I had been discouraged during the day to see the “project manager” asking on Slack our Uber team mentor about incorporating Alexa into the app. What??? They only had some HTML and CSS that wasn’t even responsive that they had pasted into Slack and hadn’t even pushed up to Github. I was not able to be there in person because of car troubles, so I was unable to add the Javascript or get them on track or understand what was drafts and what was final. I knew I could not create pages by myself because some of their strong personalities and strong opinions would not appreciate that.

On Wednesday at Maya, we met with the “customers”/ challengers. They explained that if we just built the medications page and added some particular features, that would be really helpful. Instead of listening to her and getting started, the project manager continued to ask them many, many questions, such as, would it be helpful if the users of the app could text information to it? Would it be helpful if the users could dictate into the app? What? Again, we didn’t even have Javascript at this point. There was no back end at all. I was really, really frustrated. It was very hard for me to tell other adults that they are on the wrong track and wasting everyone’s time.

After that meeting when I was ready to pull out my hair, Teacher let us in on a secret. He had framed out the whole thing in dotnet’s MVC and had pasted in the team’s latest HTML and CSS designs for the Navigation and Header. Maybe I should have done something similar. It was Partner’s idea all along to do the whole project in MVC. Perhaps because I only have access to a Window’s computer as a loaner from my brother-in-law, it didn’t occur to me. The way he did it was by having one of the controllers just return views. So, finally, finally we got started. It was down to four of us: Partner, a very nice young man from session three, me, and Teacher. Partner started working on all of the pages except medications. She was making the base HTML/ CSS using Bootstrap for as many pages as quickly as she could. She is a front-end queen and super designer. She was in the zone and was really cooking. Young Man and I used the teacher’s computer to work on the medications page. We created a JSON object and Handlebars JS and its “each” built in helper to display a table of medications from our JSON object. I finally felt like I was doing something and was excited to learn about Handlebars, something I had not used before. Young Man caught on very quickly and was a faster typist than I, so we pair programmed with him typing. We had just set up a modal to display full medications when we realized we were the very last coders at Maya and all of the organizers were just waiting for us to finish so they could close up shop. Oops. But time really flies when you are happily coding away. I loved working with Young Man. He is a bright affable person with a breadth of interests. It’s so fun to pair program and work on a focused team. I really miss it.

During the day on Thursday Young Man and one or two other members of the team continued to build out the Javascript while others of the team incorporated the HTML and CSS for a few more tweaks. I had previous appointments and was unable to attend. Working in MVC was tricky for them as many members of  the team have Macs. But, by the end of the day Thursday they had a lot more built out. There was no real data, just some JSON objects, but there were add buttons and display screens and the site mocked up some basic functionality well. I asked through slack if I could help and was told by a very nice woman on the team that they needed HTML/ CSS help for the Main Page. I wanted to help with that and do more, but I couldn’t get my Windows computer loaner to connect to the internet. It was very frustrating.

The next morning, again stuck at home, I asked on Slack many times what I could do to help, what they needed, but got no response. The launch was in the afternoon and I think the group probably felt they had everything under control and didn’t want my interference when I had never been much help to them in the first place. I added some features anyway and after doing pull requests with no response (do they even know what pull requests are? I wondered) I just incorporated them myself. Those changes were never acknowledged and after about 1/2 hour, they were overwritten, maybe accidentally and maybe on purpose. I could not tell who had overwritten them as the push came from Teacher’s computer, which I am sure was used by someone in the group who had a Mac. I asked on Slack why that was done but received no response. I think everyone was too focused on making their last minute changes. I would have been fine with this. They are a smart group of adults and had made the app work somewhat as a demo. I was discouraged later to hear that someone in the group was complaining to one of my Session 2 colleagues that he though Partner and I were no help to them. Sigh.

I am still really processing this episode. It is interesting to compare our experience with that of the other group who had three men from Session 2 as their mentors/ leaders. The other team built a fantastic app and the Session 2 men were excellent leaders and really helped their group learn.

I don’t know if it was just the personalities in our group, but I felt like Partner and I got very little respect from our team from the get go. I know in many ways I deserved that lack of respect as I was unable to get them started and frame everything out for them in a timely manner. I was unable to physically be there a lot of the time.  I am not good at managing people. I just am not. It is why I left teaching. I don’t like making people do what they don’t want to do. I wonder a little bit if it is that we are women. . . Anyway. . .

I learned that I am far from ready to manage a team. I learned that I need to be physically present to work with a new team unless everyone is used to people being remote. I learned that project managers can be very important if they focus on the right things and know what they are doing, but that they can be harmful if they don’t. I learned about HandlebarsJs. I got to know Partner better and really enjoyed spending time with her. I liked getting to know most of the team members of Session 3’s group. I loved participating in Steel City Code Fest. It is an awesome, awesome event, and was run so well. I imagine that the lessons from this experience will continue to manifest themselves for a long time. I doubt you read all of this, but if so, please don’t hold it against me. Remember that I am making mistakes and trying to learn from them. Perhaps even writing about this experience is one of those mistakes.

 

 

 

 

Building My Portfolio Website

As every new coder knows, it is important to showcase your skills, knowledge, and growth with a portfolio website, especially if you are interested in getting a job, which I certainly am. Although I knew how important that portfolio is for at least the last half of my coding bootcamp, I did not even think about getting started with the process until the bootcamp was over in December of 2016. Why? you may ask. Well, I hope here to make that clear.

At that point on a cold December morning with the thought of Christmukkah shopping hanging over my head, when I started to create the files and folders and build the HTML document for my website, I began to feel as if I had never seen HTML or CSS before. And then there was the question of what to showcase on the site. I looked back at my coding projects and realized I had no idea what any of them did or how they worked. My immediate plan when overwhelmed by my own lack of comfort relating to knowledge is always to request books from the library. So, I did that, leafed through them as they came in, and didn’t actually go back to that website until March.

In the meantime, I continued to work on a mobile app I had begun in the bootcamp, made revisions to some ugly websites as a contractor, and interned and worked in the front end of a web app for a start up. Feeling more comfortable with code in general, and front end in particular, I decided to make that attempt at my website again. After looking at the sites of some of my bootcamp classmates, I was almost too overwhelmed again to begin. I loved their sites and thought they were wonderful, but I did not want to copy them, or be thought to be copying them. No ideas came about how to be original. Time passed.

A suggestion from a graphic designer/ coding newbie I was helping with some Ruby programming finally propelled me to begin. All of the sites I looked at scrolled up and down the screen. She suggested I make my site flow in a more horizontal fashion. Ah ha! Something different, I thought. After many, many days struggling with Bootstrap’s carousel component, combining the carousel indicators with a nav menu, and making many minute adjustments to make the site work and look decent (and doing lots of stack overflowing and blog reading), I had a site that I felt looked good enough to put online. I probably spent 10-15 days of 8-12 hours getting that site to work and be “original.” Getting a domain name and a site on Github was almost too easy to be true. The site was live! It looked great on my computer, but here is how it looked on my phone:

phonescreenshotwebsite

Uh oh. Forgot to take that responsive thing very seriously. Back to the drawing board.

At this point, I decided to learn a little bit from my experience and enact something I had heard about from a guest on the Code Newbie podcast, Lil Chen. She mentioned this post, which she felt was an important one to think about when building websites or any software product. If you don’t feel like clicking on the link, I can tell you basically that the post uses building a car as a metaphor for building a product for a customer. The writer states that one should not build a product for a client by starting with a fancy car wheel and tire, but should instead begin with a bus ticket or a skateboard. The first iteration should be the minimum testable product, the point being to get it in front of the customer right away to find out more about what the customer needs exactly. The iterations should not be to build more parts for the car, but should be instead to build a scooter, then a bicycle, then a motorcycle, etc. to see how these measure up against the customers’ wishes and needs. Henrik Kniberg explains it much better and uses some real-life successes and failures to illustrate.

In my case, my customer was myself and my needs were to get that work online so I could have something to show potential employers. This need for perfection and fearing looking inadequate is essentially my problem as a coder and a person, something I am trying to work on. Voltaire wrote a great precept, which translated is essentially, “Don’t let perfect be the enemy of good.” Or, in my case, “Don’t let perfect be the enemy of getting started.”

So, instead of spending weeks getting my horizontal carousel site to be responsive, I now have a much more responsive site that scrolls up and down. It took me one day to rewrite the code. It’s still not as responsive as I would like, and is not as original as I would like, but at least it looks the same on different web browsers and computer screens of varying size, which my other did not. It has links to my code samples. And, well, it exists, which is saying something. Find it at www.cimigreen.com.