How to Find and Strip Duplicate Items from an Array in JavaScript (the Easy Way)

I found today at work I needed to identify duplicates in an array, and happened to stumble upon this highly ranked StackOverflow post full of hard to understand answers. Whenever I write code at work, I really want to make sure that I understand all of the code that I contribute to the company’s codebase and that I’m not blindly copying and pasting directly from StackOverflow. So if you’ve happened to find this blog post looking for something a little easier to understand than many of the other answers out there on the internet, maybe consider my solution:

// Duplicates: Bob, Aaron, Frank
const arrayWithDuplicates = ["Aaron", "Bob", "Chris", "Dave", "Edward", "Bob", "Aaron", "Frank", "George", "Frank", "Henry", "Bob", "Bob", "Aaron", "Aaron", "Frank"];
function findDuplicates(arrayWithDuplicates) {
let duplicates = [];
arrayWithDuplicates.forEach( (value, index) => {
const indexWhereValueFirstAppears = arrayWithDuplicates.findIndex( (value_) => {
return value_ === value;
});
const indexWhereValueLastAppears = arrayWithDuplicates.lastIndexOf(value);
if (index !== indexWhereValueFirstAppears && index === indexWhereValueLastAppears) {
duplicates.push(value);
}
});
return duplicates;
}
const duplicatesFound = findDuplicates(arrayWithDuplicates);
duplicatesFound.forEach( (duplicate) => {
console.log("Duplicate: " + duplicate);
});
view raw findDuplicates.js hosted with ❤ by GitHub

And if you need to simply strip duplicates from an array, try:

// Duplicates: Bob, Aaron, Frank
const arrayWithDuplicates = ["Aaron", "Bob", "Chris", "Dave", "Edward", "Bob", "Aaron", "Frank", "George", "Frank", "Henry", "Bob", "Bob", "Aaron", "Aaron", "Frank"];
function stripDuplicates(arrayWithDuplicates) {
let uniques = [];
arrayWithDuplicates.forEach( (value, index) => {
const indexWhereValueFirstAppears = arrayWithDuplicates.findIndex( (value_) => {
return value_ === value;
});
if (index === indexWhereValueFirstAppears) {
uniques.push(value);
}
});
return uniques;
}
const arrayWithNoDuplicates = stripDuplicates(arrayWithDuplicates);
arrayWithNoDuplicates.forEach( (unique) => {
console.log("Unique: " + unique);
});
view raw stripDuplicates.js hosted with ❤ by GitHub
 

TypeScript type = foo | bar | baz ??? Union Types Demystified

At work this past Friday I found myself exposed, exposed as an imposter: a TypeScript imposter! Often times hang loose JS script kiddies like myself can manage to fumble or fake their way through working with statically typed enterpise grade TypeScript codebases if they have to, but this past Friday a single line of code brought me to my knees! But fret not my friend, if you happen to be stumped by the following line of code:

type Something = Foo | Bar | Baz;

I have your answer: Union Types

Let me explain. If you ever run into a mysterious line of code like the one above where a type equals one thing OR another thing OR something else entirely, you are looking at a TypeScript Union Type. So what is a Union Type? A Union Type is simply a type which can include several different types. Take an “Athlete” for example. One could create a union type called “Athlete” which could be used to represent several different sub-types such as “FootballPlayer”, “BasketballPlayer”, or “BaseballPlayer”. If for some reason you happen to encounter a union type in your company’s codebase that you need to work with, there are two main things you need to know about these types.

First, if you are working with an object with a union type, know that you will be able to access all of that objects properties which are shared among all of the different types which the union type unites. So if FootballPlayer, BasketballPlayer, and BaseballPlayer all have a shared set of properties, you can access those shared properties from your object with the type Athlete.

Second, you need to know that if you try to access a property of your Athlete object which is not shared among FootballPlayer, BasketballPlayer, and BaseballPlayer, your code will crash!

However, if you really need to access a property from your Athlete object that isn’t shared among those three types, you can cast the object as a specific type to access the unique property. I know that I may be loosing some of you right about now, so… without further ado, here is a nifty little example script demonstrating how to work with TypeScript Union Types if you ever find yourself in a tricky situation trying to juggle union types:

// DEMO: Using Union-Types in TypeScript
// Question: What are Union Types???
// Answer: Union Types are TypeScript types which can be equal to many different types which often share 'union' properties amongst the various different types. For example, an Athlete Union-Type could be used to represent FootballPlayer, BasketballPlayer, and BaseballPlayer types
type FootballPlayer = {
firstName: string,
lastName: string,
jerseyNumber: number,
sport: string,
touchdowns: number,
};
type BasketballPlayer = {
firstName: string,
lastName: string,
jerseyNumber: number,
sport: string,
points: number,
};
type BaseballPlayer = {
firstName: string,
lastName: string,
jerseyNumber: number,
sport: string,
hits: number,
};
type Athlete = BaseballPlayer | BasketballPlayer | FootballPlayer;
const quarterback: Athlete = {
firstName: "Ben",
lastName: "DiNucci",
jerseyNumber: 7,
sport: 'Football',
touchdowns: 0,
};
function displayStats(athlete: Athlete) {
switch(athlete.sport) {
case "Football":
// NOTE: We can access shared 'union' properties such as firstName,
// lastName, jerseyNumber, and sport using 'athlete' which is of the
// union type 'Athlete'
console.log("Player: " + athlete.firstName + " " + athlete.lastName);
// HOWEVER: If we want to access a non-union-type property such as
// touchdowns, we cannot use 'athlete' which is of the union type
// 'Athlete'. Attempting to call athlete.touchdowns will crash the app.
// Instead, we need to type-cast athlete as FootballPlayer if we wish
// to access the 'touchdowns' property
let footballPlayer: FootballPlayer = athlete as FootballPlayer;
console.log("Touchdowns: " + footballPlayer.touchdowns.toString());
break;
case "Basketball":
console.log("Player: " + athlete.firstName + " " + athlete.lastName);
let basketballPlayer: BasketballPlayer = athlete as BasketballPlayer;
console.log("Points: " + basketballPlayer.points.toString());
break;
case "Baseball":
console.log("Player: " + athlete.firstName + " " + athlete.lastName);
let baseballPlayer: BaseballPlayer = athlete as BaseballPlayer;
console.log("Hits: " + baseballPlayer.hits.toString());
break;
default:
console.log("Error: Something went wrong...");
}
}
displayStats(quarterback);
view raw unionTypes.ts hosted with ❤ by GitHub
 

How to use Postman to Query your Company’s Backend API: A Junior Developer’s Crash Course

As a junior frontend or mobile developer, it can be quite intimidating to work with your companies backend API for the first time using a tool like Postman. In a corporate setting, there’s a good chance that you may not have access to the backend code, and that there may be little to no documentation available to you to help guide you through working with the backend API. In the real world, a lot of the knowledge regarding how the frontend and backend systems work may be locked up inside the heads of other teammates, and you may find yourself having to figure things out for yourself.

But fret not! Many companies follow a pretty straightforward convention for granting access to the backend API, so that’s what I would like to share with you here in this blog post. Obviously, companies don’t want to let anyone access their backend API. Take Snapchat for example. Snapchat doesn’t want anyone to be able to query their API and read any message they want. Snapchat only wants users to be able to read their own messages, not everyone’s messages. And this goes for pretty much all companies. Backend APIs need to be able to authenticate requests to make sure the person or computer making the request is who they claim to be and that they have access to the information they are requesting.

And how do backend APIs handle this authentication? Bearer Tokens!

Just like you have usernames and passwords for logging in to websites and apps, backend APIs have a similar method of authentication. But instead of a username and password, backend APIs roll all of that information into one– a bearer token. What is a bearer token? A bearer token is long string of text which essentially represents a username and password. You can think of it as a magic passphrase that grants the bearer access to all of the data for a given account. And why is this important? Well the bearer token is the primary thing that you will need to access your companies backend API using Postman.

So without further ado, here’s how you add a bearer token in Postman:

First, you’ll need to sift through your companies frontend code and programmatically retrieve a token for the test user you want to access the backend API as. Let’s say your company has a test user with an email address of johndoe@gmail.com and a password of p@$$w0rD123. You’ll run the development version of your companies app on your development machine, log in as user johndoe@gmail.com and see if you can programmatically retrieve a token for this test user. Somewhere in your companies codebase there will be a variable or method which will let you retrieve the user’s token. Find the token, print it to your developer console, then copy and paste it to a text file and you’re all set. Now you have the magic word!

Second, you’ll need the URL for the API endpoint which you want to query. Just like with the token mentioned above, you’ll need to hunt through your companies frontend codebase to find this, then print it to your developer console, and then copy and paste it to a text file to save it.

Third, you will need to find the JSON data which you want to send to the backend API. Typically with a POST request, you will be sending information to the backend API in the form of a JSON object. So find the JSON which you want to send the backend API, print it to the console, and copy and paste it to a text file.

Now we’re all set. We have our token, API endpoint URL, and the JSON data we wish to send via Postman. You can either fire up the Postman desktop app to send your request, or log in to getpostman.com and use their web-app. For this example, we will be making an HTTP POST request (as opposed to an HTTP GET request).

Once logged in to Postman, click on “Create a Request” to get started. Select “POST” from the dropdown menu and paste the URL for the endpoint which you wish to query. Under the “Authorization” tab, paste your bearer token. Under the “Headers” tab, enter the key “Accept” and the value “application/json”. And under the “Body” tab, select the “RAW” radio button and select “JSON” from the dropdown menu, then paste your JSON into the text field.

Press “SEND” to make your HTTP request, and that’s it!

 

How to Upgrade/Update Git to the Latest Version on Mac

Need to upgrade/update git to the latest version on your Mac? The following should do the trick:

First, if you don’t already have homebrew installed, install homebrew:

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Then update/upgrade brew:

$ brew update

$ brew upgrade

Install the latest version of git with homebrew:

$ brew install git

Now, make sure to close your terminal app. This is key because if you don’t close your terminal app and then re-open it, your terminal will not recognize the latest version installed via homebrew.

In a new terminal window, run the following to confirm you are now running the latest version of git:

$ git --version

 

Azure DevOps Search Functionality Not Working? Search Your Codebase with grep Instead

I started working my first job as a full time professional software developer recently, and frequently find myself having to search through a seemingly enormous codebase to try and find things. This function is defined here but… where in this 50,000+ lines of code is it actually called and executed?

At first I tried using Azure DevOps built-in search functionality to search through our repository, but this really just hasn’t been working. Often times I find myself searching for a function after looking at it’s definition, and the Azure DevOps search bar will not be able to find where the function is actually called.

So here is the solution I’ve stumbled upon, which I’m sure industry vets all know about already: grep

That’s it! That’s the answer to your woes if you are having trouble searching through a large codebase. Simply fire up a terminal window on your Mac, navigate to your project’s directory, and enter the following magical command:

$ cd ~/yourSuperSweetProjectDirectory

$ grep -r -i someTextYouAreLookingFor *

 

Git Reset Demystified: How to Restore Your Working Directory to Match the Master Remote Branch Exactly

Quick little tutorial here, mostly for my own personal reference, on how to restore your local working directory to match a remote master branch. Take this scenario for instance, you’re working on a project for work, maybe as a junior developer working on your first professional project, and you make a bunch of changes to your working directory that you want to throw away, and restore your project to match the remote master branch. Here are your four magic commands:

$ git checkout master

$ git fetch origin

$ git reset --hard origin/master

$ git clean -df

Similarly, if you want your local working directory running on your personal computer to match a different remote branch other than master, you can run something like:

$ git checkout users/myusername/myfeaturebranch

$ git fetch origin

$ git reset --hard origin/users/myusername/myfeaturebranch

$ git clean -df

 

[SOLVED] Amazon Fire TV Stick Web App Tester Displaying a Black Screen

Hopefully someone will find this blog post extremely helpful. Tonight I purchased an Amazon Fire TV Stick with the intention of building a cool new React app for the Fire Stick. My hacking session started off well, but I soon ran into an awful bug where my Fire Stick would continually display nothing but a black screen for my React app when using the Web App Tester.

Well after two hours of struggling with this issue, I discovered the solution to this problem: You cannot use a white background color when developing HTML5 apps for Fire TV Stick. All I had to do to get my app to start working was change the background color to purple!

When starting a new project developers tend to start with a blank canvas and a little black text, but this will not work on the Fire TV Stick. So if you find yourself running into a similar problem where you just can’t get your Fire Stick to display your Hosted HTML5 app using the Web App Tester, try changing your background color to something other than white.

 

Problems with the Google Cast SDK, Custom Receivers, and the YouTube Player API

I’ve been struggling the past couple of days experimenting with the Google Cast SDK in an attempt to create a new mobile app where users can “stumble upon” new YouTube videos and cast them to their televisions using Chromecast. However, I’ve run into a couple of big problems and would like to share what I’ve learned:

  1. The YouTube Player API for mobile apps isn’t compatible with the Google Cast SDK. If you want to show a YouTube video in a mobile app, the YouTube Player API works great. If you want to cast a video from your mobile app to a Chromecast, the Google Cast SDK works great as long as the video is hosted on your own servers. But if you want to cast a YouTube video from your mobile app using the Google Cast SDK + YouTube Player API, you are out of luck!
  2. Chromecast does play nicely however with anything you want to cast from a web browser running on a desktop or laptop computer. I didn’t run into any problems trying to “cast a tab” using YouTube embeds from my desktop or laptop computer.
  3. The last lesson I learned from experimenting with the Google Cast SDK is that Custom Receiver applications don’t seem to work. I’m sure someone out there has been able to get a Custom Receiver to work, but I personally was not. I am assuming that most people who are building apps which are capable of casting video to Chromecasts are using Styled Media Receivers. I did quite a bit of experimentation over the past few days and never ran into trouble using Styled Media Receivers (receiver apps hosted by Google), but I absolutely couldn’t get a Custom Receiver to work at all.

So there you have it! You can’t cast YouTube videos embedded in mobile apps. You can easily cast YouTube videos embedded in websites on desktop and laptop computers. And Custom Receivers for Chromecast don’t work, use Styled Media Receivers instead.

 

Surf with Swayze Privacy Policy

Privacy Policy

Your privacy is important to me. It is  my (Christopher Pedersen) policy to respect your privacy regarding any information I may collect from you on my app, Surf with Swayze.


I only ask for personal information when we truly need it to provide a service to you. I collect it by fair and lawful means, with your knowledge and consent. I also let you know why I am collecting it and how it will be used.


I only retain collected information for as long as necessary to provide you with your requested service. What data I store, I will protect within commercially acceptable means to prevent loss and theft, as well as unauthorized access, disclosure, copying, use or modification.
I don’t share any personally identifying information publicly or with third-parties, except when required to by law.


My app may link to external sites that I do not operate. Please be aware that I have no control over the content and practices of these sites, and cannot accept responsibility or liability for their respective privacy policies.


You are free to refuse our request for your personal information, with the understanding that I may be unable to provide you with some of your desired services.


Your continued use of my app will be regarded as acceptance of our practices around privacy and personal information. If you have any questions about how I handle user data and personal information, feel free to contact me (chris@topherpedersen.com).


This policy is effective as of 4 August 2020.

 

Surf with Swayze Terms of Service

Terms of Service

1. Terms

By accessing the app “Surf with Swayze,” you are agreeing to be bound by these terms of service, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. If you do not agree with any of these terms, you are prohibited from using or accessing this site. The materials contained on the Surf with Swayze app are protected by applicable copyright and trademark law.

2. Use License

  1. Permission is granted to temporarily download one copy of the materials (information or software) on Christopher Pedersen’s app for personal, non-commercial transitory viewing only. This is the grant of a license, not a transfer of title, and under this license you may not:
    1. modify or copy the materials;
    2. use the materials for any commercial purpose, or for any public display (commercial or non-commercial);
    3. attempt to decompile or reverse engineer any software contained on Christopher Pedersen’s app;
    4. remove any copyright or other proprietary notations from the materials; or
    5. transfer the materials to another person or “mirror” the materials on any other server.
  2. This license shall automatically terminate if you violate any of these restrictions and may be terminated by Christopher Pedersen at any time. Upon terminating your viewing of these materials or upon the termination of this license, you must destroy any downloaded materials in your possession whether in electronic or printed format.

3. Disclaimer

  1. The materials on Christopher Pedersen’s app are provided on an ‘as is’ basis. Christopher Pedersen makes no warranties, expressed or implied, and hereby disclaims and negates all other warranties including, without limitation, implied warranties or conditions of merchantability, fitness for a particular purpose, or non-infringement of intellectual property or other violation of rights.
  2. Further, Christopher Pedersen does not warrant or make any representations concerning the accuracy, likely results, or reliability of the use of the materials on its app or otherwise relating to such materials or on any sites linked to this site.

4. Limitations

In no event shall Christopher Pedersen or its suppliers be liable for any damages (including, without limitation, damages for loss of data or profit, or due to business interruption) arising out of the use or inability to use the materials on Christopher Pedersen’s app, even if Christopher Pedersen or a Christopher Pedersen authorized representative has been notified orally or in writing of the possibility of such damage. Because some jurisdictions do not allow limitations on implied warranties, or limitations of liability for consequential or incidental damages, these limitations may not apply to you.

5. Accuracy of materials

The materials appearing on Christopher Pedersen’s app could include technical, typographical, or photographic errors. Christopher Pedersen does not warrant that any of the materials on its website are accurate, complete or current. Christopher Pedersen may make changes to the materials contained on its app at any time without notice. However Christopher Pedersen does not make any commitment to update the materials.

6. Links

Christopher Pedersen has not reviewed all of the sites linked to its app and is not responsible for the contents of any such linked site. The inclusion of any link does not imply endorsement by Christopher Pedersen of the site. Use of any such linked app is at the user’s own risk.

7. Modifications

Christopher Pedersen may revise these terms of service for its app at any time without notice. By using this app you are agreeing to be bound by the then current version of these terms of service.

8. Governing Law

These terms and conditions are governed by and construed in accordance with the laws of TX and you irrevocably submit to the exclusive jurisdiction of the courts in that State or location.