<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kameron Kales</title>
    <description>The latest articles on DEV Community by Kameron Kales (@kameronkales).</description>
    <link>https://dev.to/kameronkales</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F160399%2F2afe7d82-3ffd-43d7-b40c-e357ad7dfe5a.jpg</url>
      <title>DEV Community: Kameron Kales</title>
      <link>https://dev.to/kameronkales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kameronkales"/>
    <language>en</language>
    <item>
      <title>How to fix JSON.stringify returning an empty object</title>
      <dc:creator>Kameron Kales</dc:creator>
      <pubDate>Mon, 06 May 2019 00:06:00 +0000</pubDate>
      <link>https://dev.to/kameronkales/how-to-fix-json-stringify-returning-an-empty-object-4man</link>
      <guid>https://dev.to/kameronkales/how-to-fix-json-stringify-returning-an-empty-object-4man</guid>
      <description>&lt;p&gt;I write a lot of Javascript and ran into a pretty awful bug today that took me 3 hours to figure out. In the hopes of this saving someone else an equal amount of time I am writing about how I fixed it here. &lt;/p&gt;

&lt;p&gt;I am developing a chrome extension that makes the internet private again. No tracking, no bad actors, etc. I have written a few libraries to use for the project for simple things like auth with google and http requests. &lt;/p&gt;

&lt;p&gt;I usually use things like axios but wanted to roll my own and interface with raw XML HTTPRequests. Last night I was running out the door but made a few code changes I didn't quite think through. Bad move. &lt;/p&gt;

&lt;p&gt;I have 2 methods that ended up being the way to fix. &lt;/p&gt;

&lt;p&gt;In my auth.js method I was passed an object from Google like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "email": "kameronkales", "id": 1298179834}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In my history.js I was creating what I thought was an object (but was really an array).&lt;/p&gt;

&lt;p&gt;I created the array like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var i;
var example_list = []
for (i = 0; i &amp;lt; bad_list.length; i++) {
var clean = bad_list[i]
    example_list.push(clean)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This was not doing what I thought. &lt;/p&gt;

&lt;p&gt;When I console.logged the data from example_list I was getting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
    0: "https://google.com",
    1: "https://google.com",
    2: "https://google.com
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which, now seems obviously wrong. But I didn't realize until looking at the data. &lt;/p&gt;

&lt;p&gt;JSON.stringify doesn't know what to do with those int fields. So, it drops them. &lt;/p&gt;

&lt;p&gt;When I would run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JSON.stringify(example_list)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I would be returned this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it drove me insane! Because I knew the array had fields in it. But I wasn't paying enough attention (I know, I know. Won't do that again.)&lt;/p&gt;

&lt;p&gt;I ended up being able to fix this by the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var urls = {}   &amp;lt;= an actual object

.....HTTP requests to get the data I wanted 

urls['data'] = data

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This now returns a nice object that looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    'data': 'https://google.com',
    'data': 'https://google.com',
    'data' : 'https://google.com'
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are a ton of ways to clean this up and format better. But I spent way too long trying to figure out why this simple method didn't work the way I wanted it too. &lt;/p&gt;

&lt;p&gt;Hopefully this saves you some time. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Lambda Function Got Ya's</title>
      <dc:creator>Kameron Kales</dc:creator>
      <pubDate>Thu, 02 May 2019 14:29:28 +0000</pubDate>
      <link>https://dev.to/kameronkales/lambda-function-got-ya-s-3j3o</link>
      <guid>https://dev.to/kameronkales/lambda-function-got-ya-s-3j3o</guid>
      <description>&lt;p&gt;I am working on a new product for a privacy focused startup. We protect customers from logging, tracking and all that bad stuff we've come to dislike. &lt;/p&gt;

&lt;p&gt;We are starting with a chrome extension as an MVP. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;(if you know of a chrome extension with &amp;gt;30,000 users that hasn't been updated in &amp;gt;18 months, email me. I will pay a referral fee.)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside of our chrome extension we're going to do a few different things. Mainly protect your history. To do this, we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Account Creation&lt;/li&gt;
&lt;li&gt;Account Log In&lt;/li&gt;
&lt;li&gt;API to check against &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want to manage all of the typical ECS/Docker/ELB/Route53 crap that comes along with getting a service out to customers these days. So I decided to write these services in a serverless style. &lt;/p&gt;

&lt;p&gt;This post details some common mistakes I made, and how I have fixed them.&lt;/p&gt;

&lt;p&gt;One thing to note, I generally do not like adding packages that introduce another "dialect" to get the job done. When I have done this, it often abstracts away what is actually happening, and makes it a struggle to debug. &lt;/p&gt;

&lt;p&gt;I want to stay in plain javascript, python or go as much as possible. The bugs are more predictable and docs clearer. That is not to say my way is the best, just know that this blog will only focus on my personal approach.&lt;/p&gt;

&lt;p&gt;Last administrative thing: I hate blogs that don't show the FULL code. So we will. It doesn't help if half of what you need to reproduce is missing. &lt;/p&gt;

&lt;p&gt;First thing to realize, when you create a lambda function you upload a zipped file with a flat file structure to Lambda. &lt;/p&gt;

&lt;p&gt;If you're using Node, that means you must zip up your node_modules. If you're using Python you will do the same with your requirements.txt packages. &lt;/p&gt;

&lt;p&gt;There are a few easy ways to do this: &lt;/p&gt;

&lt;p&gt;In node =&amp;gt; I created a file called build_upload.sh. That file houses the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip -r ./dev/lambda_function.zip ./node_modules/* ./main.js -x "./dev" &amp;amp;&amp;amp; aws s3 cp ./dev/lambda_function.zip s3://$1-$2/$2/v$3/lambda_function.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This bash file takes 3 variables: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$1 = stage (for example, dev)&lt;/li&gt;
&lt;li&gt;$2 = integration name (for example, stripe-integration)&lt;/li&gt;
&lt;li&gt;$3 = version number (for example, 1.0.0)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose to set these variables up like this. The s3://$1-2 portion combines to correspond with my bucket name. If you named your bucket differently please alter the example! &lt;/p&gt;

&lt;p&gt;A working example with the variables filled in would be: &lt;/p&gt;

&lt;p&gt;bash build_upload.sh dev stripe-integration 1.0.0&lt;/p&gt;

&lt;p&gt;That would fill the code in from above and produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip -r ./dev/lambda_function.zip ./node_modules/* ./main.js -x "./dev" &amp;amp;&amp;amp; aws s3 cp ./dev/lambda_function.zip s3://dev-stripe-integration/stripe-integration/v1.0.0/lambda_function.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This then shows up version controlled in your s3 bucket. Which lets you roll back at any point needed. There is an infinite number of other set up options you can get rolling but this was the easiest way for me to get a working build and deploy sequence going. &lt;/p&gt;

&lt;p&gt;In python,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip -r9 ../lambda.zip * -x "bin/*" requirements.txt setup.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'd suggest using Terraform to manage all of this. The best way to do this is to upload the code to an s3 bucket =&amp;gt; grab the most recent version via Terraform =&amp;gt; deploy onto Lambda.&lt;/p&gt;

&lt;p&gt;I provided the node example above showing how to do that. The python one only builds the updated zip locally. &lt;/p&gt;

&lt;p&gt;Here is the block for the Terraform resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_lambda_function" "check_file_lambda" {
    filename = "${var.function_path}"
    function_name = "${var.function_name}"
    role = "${aws_iam_role.check_file_lambda.arn}"
    handler = "${var.handler}"
    runtime = "${var.runtime}"
    timeout = "${var.timeout}"
    source_code_hash = "${base64sha256(file("${var.function_path}"))}"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In Terraform you have a file called variables.tfvars. All of the mentions of ${var.function_path} or similar are variables stored in that file. These variables are set up with a syntax like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "function_path" {
    description: "The path to the lambda function package you're deploying"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can additionally add a default field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "function_path" {
    description: "The path to the lambda function package you're deploying"
    default: "../../lambda_function.zip"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Without the default field the command line will prompt you to enter the definition of default when you run Terraform plan or Terraform apply. &lt;/p&gt;

&lt;p&gt;Moving on, the one field we want to pay special attention to is the source_code_hash. This will take a hash of our source code and upload to lambda new versions when we run Terraform apply. &lt;/p&gt;

&lt;p&gt;You can also do this other ways, but since I use Terraform for everything (s3, functions, cronjobs, database, routing, etc) I deploy changes through it. #TeamNeverUseAWSUI&lt;/p&gt;

&lt;p&gt;That magic little field will make it so I can zip up changes and re-deploy from anywhere. &lt;/p&gt;

&lt;p&gt;You might run into not being able to edit the code in the online editor. My python function didn't let me, but my node package did. For this, I don't currently have a great solution. But if anyone does, please let me know!&lt;/p&gt;

&lt;p&gt;I like to write function based code. This means my code very often looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def initial_function():
        blah blah blah 
        blah blah blah 
        format_data(blah)

def format_data(blah):
        blah2 blah2 blah2
        blah2 blah2 blah2
        insert_data(blah2)

def insert_data(blah2):
        blah3 blah3 blah3 
        blah3 blah3 blah3

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One mistake I made early was not quite understanding how to integrate this into the lambda function syntax of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def handler(event, context):
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To do this, I altered the above such that the handler function calls the initial_function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def handler(event, context):
    initial_function()

def initial_function():
        blah blah blah 
        blah blah blah 
        format_data(blah)

def format_data(blah):
        blah2 blah2 blah2
        blah2 blah2 blah2
        insert_data(blah2)

def insert_data(blah2):
        blah3 blah3 blah3 
        blah3 blah3 blah3
        return 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can pass params from the event if you need. This is a basic example showing how to make your local code work in Lambda. &lt;/p&gt;

&lt;p&gt;I did the exact same with Node shown below:&lt;/p&gt;

&lt;p&gt;One key reminder: Once your function is completed, remember to call the callback. The callback(null, response is shown below)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.handler = function (event, context, callback){
    .......... bunch of code here 
    .......... bunch of code here
    .......... bunch of code here
    .......... bunch of code here
    callback(null, response)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you have gotten this far, you should have a working lambda function testable through the console. You just click the test button and make a fake test (if your function depends on params then make it more realistic). &lt;/p&gt;

&lt;p&gt;You can also create a file called invoke_lambda.sh&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda invoke --region=us-east-1 --function-name=$1 $1.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This takes 1 variable (as shown by $1). The function name. It outputs the result of the function into a file titled function_name.txt. &lt;/p&gt;

&lt;p&gt;You can then open it or read via cat from your terminal. &lt;/p&gt;

&lt;p&gt;This makes it super easy, to once again, figure out what is going on without opening Amazons impossible UI. &lt;/p&gt;

&lt;p&gt;One issue I ran into with our scraping infrastructure was lambda timing out. It is initially set at a 3 second time out. I altered to 30 and was golden once again. &lt;/p&gt;

&lt;p&gt;You may also run out of memory. This is a common issue people run into. I didn't have the same problem but if you do, there is a slider in the UI or one field in Terraform to update. &lt;/p&gt;

&lt;p&gt;The next logical step is to create a custom domain from your lambda function. So you can do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.kameronkales.com/stripe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;to do a get request on the stripe-integration lambda function.&lt;/p&gt;

&lt;p&gt;I can update this later if people want to know about that. It is pretty simple: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request a certificate from AWS Certificate Manager&lt;/li&gt;
&lt;li&gt;Do the verification (DNS or Email)&lt;/li&gt;
&lt;li&gt;Set up a CName such that your desired route is available at your cloudfront distribution url &lt;/li&gt;
&lt;li&gt;map the /route to that domain in the custom domain portal of api gateway. &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>python</category>
      <category>lambda</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
