Category Archives: Web Dev

Sprint 3 Retrospective

            As you may hope, or expect, this final sprint is where everything really came together, and we were firing on all cylinders. We had consistent communication when needed and otherwise had tasks we could work self-sufficiently on in the meantime. Our task board was positively stuffed with tasks that expressed the minute details of our process, and we managed to complete an incredible amount of their weight considering how many there were. Having spent the first sprint unsure of what tasks actually needed doing, and the second iterating on what we had created, I believe this was the moment all the building blocks fell in place; and it felt, at least personally, that tasks were clear and specific, comprised of all the things I wished to improve from the rough iterative process mentioned in the second sprint.

            I think having finalized our UI design, or at least cemented the layout, allowed for easier improvement of said design. In many ways, having a finalized user flow in place made so that much of the non-style code could be refactored to store and manage information more effectively. For instance, as mentioned in the note above, I began with calling REST API to log transactions in the weight entry component where the necessary information would end up: student ID and weight. After refactoring, I broke both the storage and management of guests into a service which could be more easily accessed by any component and centralized any API calls made using guest information. This worked perfectly except for a single instance, where I needed this service to call another component. Services can be easily imported by components but sending information to a specific component from a service is more complicated. As I understand, the code I used subscribes the component I needed to speak to, to the service, which then can send a signal to that component, which in turn calls one of that component’s methods.

            Regarding what did not work, it is a combination of both personal and group strategy. While we each could work effectively alone on our own independent portions, it meant that we all became intimately familiar with only one or two aspects of the project. This has especially caused problems most recently with trying to move our respective portions into Docker, as I was the only one who knew next to nothing about Docker. Therefore, I could not help my group members work on any problems my front end code may have caused. I see not keeping up with my group member’s Docker progress as a personal failing. Now both in this class and in the workforce to come, I am wishing I had this knowledge of such a powerful and seemingly common framework. Otherwise, I am very proud of the work my group members did and think given some more cross-cutting training we would be that much more of an effective team. Especially given everything that has been going on we have managed to put together a site that is nearly ready to roll out. (With the caveat, of course, that it may not be absolutely perfect but can perform all the tasks necessary).

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

Sprint Two Retrospective

If the first sprint was crawling, then this sprint we moved straight to running. When considering the shorter length of the first sprint we appropriately stuck to smaller “set-up” or preparatory goals. This time, we began actually building our site in earnest. My focus, as evident from the list above, is web design and development for the UI/UX. At the beginning of this sprint, while planning, I was at a loss to quantify what exactly needed to be done. One may notice that many of these issues were posted within the last few days of this sprint. Considering I haven’t built that many websites, and none with so specific of a purpose, my thought was that I didn’t know what I needed until I had it: I would simply figure things out as I built them. This flies in the face of any good practice, and I will of course avoid such practices moving forward, but given my inexperience I had to lay the tracks in front of us as we steamed on. This manifested as an incredibly broad task, “Implement the UI from the wireframe”, with us then filling in the gaps after.

This worked, but not terribly well. It has given us a working front, albeit with some missing or broken features, but a code base desperate for refactoring. As with last semester, I often would end up learning about a useful feature after I had already beat my head against the problem and found a roundabout way of solving it. For instance, despite implementing a new directive, I did not know that services could be split off as well and shared by all components. The list of all Guest IDs, for example, would be best shared by all components instead of how it currently is implemented, which is a hodgepodge of emitters with no “real” persistence between components. It can currently pass guest IDs effectively between them, but this could be done, presumably, much easier using a service. I’m not completely certain either, it will be another instance of a new technique we’ll have to learn as we implement it, but I would have liked to have started here rather than arrive here after what will become somewhat wasted effort.

I say somewhat wasted, but in reality, it doesn’t hurt to know how to approach problems in many different ways. I believe using emitters is a valuable skill to have. Additionally, I now know at least three different ways to embed svg into a web page, with each successive one being more effective than the last but with all having their uses. I feel that I am certainly improving as a web developer, with each new misstep putting me in the direction of a better solution. However, I have a lot to learn in regard to version control systems. I caused a few headaches for poor James, who kindly walked me through all my poor practices. I know now never to push directly to the master branch for a new feature and utilize merge requests effectively. Also, never copy paste anything, because they are treated as new files even if they have the same exact content and will cause innumerable conflicts. In addition, Pawel and I ended up both independently working on the same issues, but we have discussed ways to avoid these situations moving forward. Even with all the growing pains mentioned and those involved in moving everything online, I believe we have found ways to be an effective team as well.

For this next sprint, our tasks already look much better, each containing the fine detail of work that needs to be done in order to reach our next project iteration. There are considerably more tasks, and none that are as horribly broad as many of those in this sprint. We possess a better sense of what needs to be done, and we can act upon it. By applying all the lessons learned thus far I believe we are closer and closer to something that can actually be used by the food pantry and should all be proud of that fact.

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

Dig Deeper: Finding the Marianas Trench of knowledge

This particular pattern is quite resonant with me, or at least the context section of it, considering it describes my entire academic experience in computer science fairly well. An excellent analogy would be a lake a mile wide but a foot deep; or at least it would be but a foot is very generous to the depth of my knowledge and a mile is delusional considering the limited scope of languages and tools I am familiar with. However, the sentiment expressed in this section still holds: “You learn only enough about any tool to get today’s job done”. I’m ‘you’. It is not for a lack of interest, at least not in all the subjects we have covered, that I do not go very deep into them – it’s exclusively a matter of time and mental resources. I have found that I have only had the time and energy to cover a subject as much as it takes to complete the require work or project associated it.

An example that comes to mind was last semester when working on both a REST API and Angular web front end – and by working on, I mean learning frustratedly as quickly as possible while working with both for the first time independently. There felt like so little time that I had to at one point neglect the JDBC features built into the Spring Initializer because I simply did not have the time to dig through the documentation. I had to instead use a less efficient and redundant method I knew well. Additionally, on the front-end side, I was able to brute force a lot of scalability because it was easier to use the limited knowledge I had to write ngOnInit and onResize methods to handle window sizing; as opposed to learning built in scalability tools or utilizing CSS more effectively.

To learn these methods would have taken a considerable amount of time that I simply did not have. Luckily this semester the pace at which the site is being built is much more manageable, as is the distribution of work amongst four people. So, with this time I hope to gain a better understanding of the tools and techniques I wish to utilize, before I do so. The pattern suggests writing a blog post, unfortunately this one does not fit that prompt. Speaking of which, I find the idea of going back to read a technological paper from 1976 to be a massive waste of time – but that’s just me. Regardless, and as always, I will seek a more reasonable middle ground between the pattern and what I find effective.

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

CS343 Final Project – Blog 3

In this blog I hope to show what a beast typescript animations can be. To do so I’ve isolated one animation in a set of ten that control the slide in animation for each page.

transition('HomePage <=> *', [
  style({ position: 'relative' }),
  query(':enter, :leave', [
    style({
      position: 'absolute',
      top: 0,
      left: 0,
      width: '100%'
    })
  ]),
  query(':enter', [
    style({ left: '-100%'})
  ]),
  query(':leave', animateChild()),
  group([
    query(':leave', [
      animate('400ms ease-out', style({ left: '100%'}))
    ]),
    query(':enter', [
      animate('400ms ease-out', style({ left: '0%'}))
    ])
  ]),
  query(':enter', animateChild()),
])

On the first line you’ll notice I have the transitions from the element I currently am on, “HomePage”, representing the Home Page component, to a placeholder representing any other component. Next, there are queries which represent what to do when the animation is triggered. The components slide in from the left and send the old component out the same way, and that is what the left 0% and 100% would seem to represent; with of course a set time for the duration of the animation.

           The result of this is that the new component is placed virtually to the left of the current component, then the new component is slid in eventually having its left side arrive at the 0% mark as expected, while the old component has its left side shifted to 100%. This making it virtually placed to the right, where it presumably is then removed.

           When I first added these animations, they would not trigger correctly and often only in one direction. As mentioned, there are a total of ten, which is the total after added one to represent moving from any defined page to any random page, or vice versa. That way no matter what page you are on the correct animation triggers. However, the next problem I ran into was that adding a whole other element to the left of a page, essentially making the page 200% wide even for a split second, would cause the horizontal scroll bar to appear and the window would jitter. This was quickly remedied by turning off the x-overflow, or rather setting it to hidden, in the css properties for the div in the app component html that contains the router for all these elements. With that done, I had slick page animations and no nonsense!

           One last touch added was something I realized the webpage could use when testing the animations. I noticed that when the animations trigger it would slide in the other page but the viewport would remain at the same level as the last page. It didn’t make much sense to me that a page be loaded in with the user at the bottom of it. So I added an additional method to scroll the user to the top of page each time they clicked on a button and a new element slid in.

<button mat-flat-button color="primary"
        routerLink="/about-me" (click)="returnToTop()"
        [ngStyle]="{'font-size': button_font_size + 'pt'}">
  About Me
</button>
returnToTop() {
  window.scrollTo({
    top: 261,
    left: 0,
    behavior: 'smooth'
  });
}

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

CS343 Final Project – Blog 2

On the last blog I had mentioned the painstaking process of getting my sticky header to function correctly and especially so when accounting for the top margin and mobile scaling. I have provided the code below for the sticky header.


 @HostListener('window:scroll', ['$event'])
 onWindowScroll(e) {
   if (window.pageYOffset > 251) {
     let element = document.getElementById('navbar');
     element.classList.add('sticky');
     element.classList.remove('non_sticky');
     if(window.innerWidth <= 850) {
       this.top_padding_var = 87;
     } else {
       this.top_padding_var = 43;
     }
   } else {
     let element = document.getElementById('navbar');
     element.classList.remove('sticky');
     element.classList.add('non_sticky');
     this.top_padding_var = 0;
   }
 } 

What this is doing, essentially, is adding the sticky header to the document when past a certain point and removing the non-sticky variant. The toolbar is nested inside a non-sticky div, inside the sticky div, which is present at the top of the page below the header. When scrolling past a certain point the non-sticky version is “swapped” for the sticky variant which is fixed to the top of the page. Here below is the code for this sticky component where you can get a better idea of what I mean by nesting.


<header class="animated fadeInDown" id="navbar">
  <div class="non_sticky" [ngStyle]="{'height':header_height}">
    <app-toolbar></app-toolbar>
  </div>
</header>

You can see here as well that the height of the container for the toolbar is determined by the variable, header_height. I mentioned previously as well that considerations were made for mobile use and this is one. Below is the method that determines this variables value.


resize() {
  if(window.innerWidth <=850){
    this.header_height = 40;
  }
  else{
    this.header_height = 60;
  }
}

Increasing the height makes readability on mobile more effective as well as providing enough space for the buttons to fit in the bar. Some may have noticed a variable being assigned in addition to the sticky-header being added/removed, which highlights another challenge of this particular bit of styling. As mentioned, the sticky header simply swaps in a fixed version of the normal toolbar, but in doing so this new fixed element has a higher z-index and does not “touch” the other elements.

As a result, this new element naturally covers whatever was behind it just a moment ago. To remedy this, I added this variable to the method to dynamically add padding to push the elements on the page back down where they belong. Honestly, it feels like trickery the way everything works together but when it does its nearly seamless unless you know exactly what to look for. In the next blog I will discuss a part of this element that I did not include previously: animations.

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

CS343 Final Project – Blog 1

Since this semester began, I’ve known exactly what I wanted to do for my final project, and even before the semester I’ve had this project kicking around my head. Ever since I saw my good friends personal site years ago, I thought it may be exciting to create my own, even before I even considered doing computer science. So, it should be obvious then, when I found out we would be creating a web page for our final project I knew this was the perfect opportunity to finally begin this project.

I knew that this personal – or rather, professional – site would be an interactive resume of sorts, a really incredible showing of capability that I could link to on resumes and in online professional profiles (LinkedIn, Handshake, etc). Consider this exchange:


“Have you done any web development?” asks a potential employer.

“Well sir/madam/neither, if you simply navigate to [web address] you’ll see the extent of that experience”.

“My goodness, this website looks amazing! I have no choice but to make you the president”.


As such it has to look good, like really good, you don’t become the president for nothing (you get it for being related to someone important). So, if I wanted a website that would make someone important adopt me, I needed to perfect the aesthetics of the website. I would need interactive elements and animations, a pleasing color palette, a readable layout, and of course sections on who I am and what my accomplishments are. I will, of course, not be linking this blog to it considering the beginning of this paragraph.

The first element I knew I wanted was a sticky header, or a toolbar that would “stick” to the top of the page once you scrolled down far enough for the top of the toolbar to touch the top of the page. This would mean that users could change page even while far past the header of the site. Another element I wanted was large tiles representing each page that would expand to fit the whole screen when clicked. However, I realized that it was incredible difficult to implement and also redundant considering I already had a way to access any other page at any point a user may be on said page.

I would reach the previous conclusion long after I had already begun, starting with the sticky toolbar. Folks online have implemented similar designs, so I began with those that were most effective and simple as a template. The way it works is actually very clever: a typescript method is used to check the yOffset of the page and if it goes past the offset of top of toolbar the toolbar is changed from a regular element to one that is fixed at the top of the page. As such, the elements on the page below would normally be covered slightly by this bar, however I have it dynamically add to the top-margin of the page to shift the content down appropriately. When this happens, by painstakingly finding the exact right values, it all appears perfectly seamless.

This work took, no joke, 4 hours or more, as I added scaling for page width such that when the page is shrunk horizontally as it would be on mobile the header and toolbar grow in height to accommodate the text and buttons correctly. However, I’ve already gone long on this blog so I will continue in the next one!

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.