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.

Advertisements

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.