<?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: Derek Gavey</title>
    <description>The latest articles on DEV Community by Derek Gavey (@dgavey).</description>
    <link>https://dev.to/dgavey</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%2F344008%2Fb979b7c5-196f-478f-85e8-92a6e3871ee4.jpeg</url>
      <title>DEV Community: Derek Gavey</title>
      <link>https://dev.to/dgavey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dgavey"/>
    <language>en</language>
    <item>
      <title>Zip your own Netlify functions for better dependency control</title>
      <dc:creator>Derek Gavey</dc:creator>
      <pubDate>Sun, 25 Oct 2020 22:53:53 +0000</pubDate>
      <link>https://dev.to/dgavey/zip-your-own-netlify-functions-for-better-dependency-control-24bn</link>
      <guid>https://dev.to/dgavey/zip-your-own-netlify-functions-for-better-dependency-control-24bn</guid>
      <description>&lt;p&gt;When I was working on my side project &lt;a href="https://dedolist.com"&gt;Dedolist&lt;/a&gt;, which is mostly hosted on &lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt; I started using Netlify functions. They are a really easy way to create small AWS Lambda functions.  &lt;/p&gt;

&lt;p&gt;In their simplest form you just created a file in your "functions" folder and they get deployed as a lambda function.  Unfortunately I required a bit more control over the functions than the simplest case.&lt;/p&gt;

&lt;p&gt;I needed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To access a file locally that is deployed with the function.&lt;/li&gt;
&lt;li&gt;Maintain the functions own dependencies that were not part of the main project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It took a few hours and reading a lot of forum posts and sample projects, but I finally was able to figure it out.  I'm hoping to save you some time by showing you the exact steps you need to take to accomplish this.&lt;/p&gt;

&lt;p&gt;Netlify's build tools does try and smartly build your functions, however there are some scenarios where it may fail to find all the dependencies. There is also a limit to the size of the function that AWS lambda accepts (50MB) and this technique gives you more control over what is included in your final functions.&lt;/p&gt;

&lt;p&gt;I have all the code for this demo in this &lt;a href="https://github.com/dgavey/netlify-functions-example"&gt;repository&lt;/a&gt;.  I'll point out some of the specific changes I made to deploy my bundled functions.&lt;/p&gt;

&lt;p&gt;First off, in general the way to bundle your functions is you need to compress each function and all of it's dependencies in a single zip file. Just like the simplest form of Netlify functions, you can put each zip file in your functions folder and it will get deployed. &lt;/p&gt;

&lt;p&gt;In order to be able to test your functions locally using &lt;code&gt;netlify dev&lt;/code&gt; you need to be able to specify a separate folder for your "development" and "production" functions.  It's easy to do that by changing your &lt;code&gt;netlify.toml&lt;/code&gt; and adding environment specific configurations below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#netlify.toml in root of project

[build]
  functions = "functions"

[dev]
  functions = "functions-dev"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see above, new now specify two different folders for function in "build" and "dev". So now when you run &lt;code&gt;netlify dev&lt;/code&gt; the functions can be modified in the functions-dev folder and you can test them there.&lt;/p&gt;

&lt;p&gt;Now lets look at what a function in the "functions-dev" folder looks like.  Take a look at the structure below for a function called "hello-dev".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;functions-dev
  hello-dev
    node_modules
    package.json
    hello-dev.js
    .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything in the folder &lt;code&gt;hello-dev&lt;/code&gt; will be zipped and become one lambda function. You can have multiple functions and even mix your single file functions with folder based ones.&lt;/p&gt;

&lt;p&gt;For this example the package.json has a dependency for &lt;a href="https://github.com/jeremydaly/lambda-api"&gt;lambda-api&lt;/a&gt;.  No other function will have this dependency only this one.&lt;/p&gt;

&lt;p&gt;The magic is in the top level package.json file and the build commands. Let's look at each part of the build system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NODE_ENV=production npm-run-all build:*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:static&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eleventy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:functions-install-dependencies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd functions-dev; for i in */; do cd ${i%/}; yarn; cd ..; done;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:zip-functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd functions-dev; for i in */; do zip -r &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;../functions/${i%/}.zip&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;$i&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;; done;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:copy-single-functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cp ./functions-dev/*.js ./functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eleventy --serve --quiet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;strong&gt;"build"&lt;/strong&gt; simply runs all the build steps and signifies the node production environment. This is the command that Netlify calls when building the production application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"build:static"&lt;/strong&gt; Is just the normal Eleventy build command, not part of the functions build step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"build:functions-install-dependencies"&lt;/strong&gt; does what is says.  It enters into each folder and install the dependencies for each function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"build:zip-functions"&lt;/strong&gt; zips each folder into the production functions folder so Netlify knows to create it.&lt;/p&gt;

&lt;p&gt;Finally &lt;strong&gt;"build:copy-single-functions"&lt;/strong&gt; copies any single file lambda functions you might have.&lt;/p&gt;

&lt;p&gt;You can see a working example from the &lt;a href="https://github.com/dgavey/netlify-functions-example"&gt;repository&lt;/a&gt; on &lt;a href="https://dgavey-netlify-functions-demo.netlify.app/"&gt;https://dgavey-netlify-functions-demo.netlify.app/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There was a couple of strange issues I ran into with the Netlify CLI that should be noted.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It won't serve functions on a purely static site, so I included an extremely basic eleventy generator.&lt;/li&gt;
&lt;li&gt;It won't allow access to functions in folders unless there is a build command in dev environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hopefully this can help you get more control over the building of your functions with Netlify.&lt;/p&gt;

&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@tonyphamvn?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tony Pham&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>netlify</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Simple Drag and Drop in Ember Octane</title>
      <dc:creator>Derek Gavey</dc:creator>
      <pubDate>Thu, 09 Apr 2020 02:05:35 +0000</pubDate>
      <link>https://dev.to/dgavey/simple-drag-and-drop-in-ember-octane-466i</link>
      <guid>https://dev.to/dgavey/simple-drag-and-drop-in-ember-octane-466i</guid>
      <description>&lt;p&gt;This tutorial will show you how to implement a drag and drop interface in Ember Octane without the use of any addons.  It does assume you have at least a basic understanding of &lt;a href="https://emberjs.com/editions/octane/"&gt;Ember Octane&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have had a lot of experience with the Javascript drag and drop API in the past. In fact, I even maintain the &lt;a href="https://github.com/mharris717/ember-drag-drop"&gt;ember-drag-drop&lt;/a&gt; addon. Though I must admit that it is not very up to date anymore and to some extent with Ember Octane is not really needed as much as it was before.&lt;/p&gt;

&lt;p&gt;First we are going to implement a very basic drag and drop.  One of the big changes in Ember Octane that makes implementing a drag event easier is &lt;a href="https://www.pzuraq.com/coming-soon-in-ember-octane-part-4-modifiers/"&gt;modifiers&lt;/a&gt;. In simple terms modifiers allow us to access native DOM elements and events in our templates.&lt;/p&gt;

&lt;p&gt;First lets setup the template elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="c"&gt;{{! simple-drag.hbs }}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropZone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Drop Zone
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dragMe"&lt;/span&gt; &lt;span class="na"&gt;draggable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;   
    Drag Me
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see we now have two simple div's. One for the drop area and one for the draggable element. The only thing here to notice is we have added the &lt;code&gt;draggable&lt;/code&gt; attribute to the "drag me" element. This just notifies the browser that this div element is now draggable. You can only pass true or false to it.&lt;/p&gt;

&lt;p&gt;Before the draggable element is active though, you are &lt;strong&gt;required&lt;/strong&gt; to have a &lt;code&gt;dragstart&lt;/code&gt; event attached to the element. Lets add that now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="c"&gt;{{! simple-drag.hbs }}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropZone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Drop Zone
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragstart"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dragHasStarted&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dragMe"&lt;/span&gt; &lt;span class="na"&gt;draggable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;   
    Drag Me
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are using the on modifier to attach to the &lt;code&gt;dragstart&lt;/code&gt; javascript event.  Here is the class for that component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//simple-drag.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SimpleDrag&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dragHasStarted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drag has started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see that the &lt;code&gt;dragHasStarted&lt;/code&gt; is an "action".  You must decorate your function with action when using it with a modifier. The main reason for this is that it takes care of binding your event handler so you can access &lt;code&gt;this&lt;/code&gt; and it will reference your component class.&lt;/p&gt;

&lt;p&gt;Now if you drag your element it will have the default dragging behaviour in your browser.&lt;/p&gt;

&lt;p&gt;To set up the drop events add to the component template and class the two required drag events &lt;code&gt;drop&lt;/code&gt; and &lt;code&gt;dragover&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="c"&gt;{{! simple-drag.hbs }}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; 
  &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"drop"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dropItem&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; 
  &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragover"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dragOver&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropZone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Drop Zone
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragstart"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dragHasStarted&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dragMe"&lt;/span&gt; &lt;span class="na"&gt;draggable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;   
    Drag Me
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//simple-drag.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SimpleDrag&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dropItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Item dropped&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dragOver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dropEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;move&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dragHasStarted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drag has started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In order for the &lt;code&gt;drop&lt;/code&gt; event to fire it &lt;strong&gt;must&lt;/strong&gt; also have a &lt;code&gt;dragover&lt;/code&gt; event, so make sure you have one even if it does nothing.  Two other things to note with this code. &lt;/p&gt;

&lt;p&gt;The first is that we are accessing the native "event" in the &lt;code&gt;dropItem&lt;/code&gt; function.  We use it to &lt;code&gt;preventDefault()&lt;/code&gt;.  This is also important as after you drop an item it can trigger events on the drop target that you may want to avoid.&lt;/p&gt;

&lt;p&gt;The second is in the &lt;code&gt;dragOver&lt;/code&gt; function we are setting the dropEffect to "move".  This tells the browser what kind of action we intend to take when the item is dropped.  For more information see the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API"&gt;MDN docs&lt;/a&gt;.  Also, be careful with the &lt;code&gt;dragover&lt;/code&gt; event as it fires multiple times per second so you don't want to do too much here.&lt;/p&gt;

&lt;p&gt;Ok, this should now allow you to get console logs on start of drag and drop. Using those two event functions you should be able to implement most of the logic that you want the drag and drop action to perform.  &lt;/p&gt;

&lt;p&gt;There are a number of other drag events though. Lets take a look at the final full code that implements a few more events that give the user a more interesting interface and you more control over it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="c"&gt;{{! simple-drag.hbs }}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; 
    &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"drop"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dropItem&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; 
    &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragover"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dragOver&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
    &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragleave"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dropLeave&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
    &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragenter"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dropEnter&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropZone &lt;/span&gt;&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;overDropZone&lt;/span&gt; &lt;span class="s2"&gt;"dropZone-over"&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Drop Zone
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; 
    &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="s2"&gt;"dragstart"&lt;/span&gt; &lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;dragHasStarted&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dragMe"&lt;/span&gt; 
    &lt;span class="na"&gt;draggable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;   
    Drag Me
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Drag Status: "&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;statusText&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;"&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//simple-drag.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@glimmer/component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ember/object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tracked&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@glimmer/tracking&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SimpleDrag&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tracked&lt;/span&gt; &lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tracked&lt;/span&gt; &lt;span class="nx"&gt;overDropZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dragHasStarted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drag has started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dropItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drop Has Completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overDropZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dragOver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;dragEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dropEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;move&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dropLeave&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drag has left drop zone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overDropZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;action&lt;/span&gt; &lt;span class="nx"&gt;dropEnter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drag is entered Drop Zone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overDropZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So we have added a few more events like &lt;code&gt;dragenter&lt;/code&gt; and &lt;code&gt;dragleave&lt;/code&gt;. These allow us to let the user know when they are over the drop zone by adding a class.  We have also added a status text so you can see what events are firing and when. &lt;/p&gt;

&lt;p&gt;You can try this final code out for yourself on this &lt;a href="https://ember-twiddle.com/8912fd46f7a66c92a2118c8199b17c2a"&gt;Ember Twiddle&lt;/a&gt;.&lt;br&gt;
You can find the full &lt;a href="https://github.com/dgavey/drag-drop-ember-octane-examples"&gt;project on github&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;I haven't covered accessibility support in this tutorial, but that must be considered to make the drag and drop inclusive for all users. You will at a minimum want to add some keyboard event support.&lt;/p&gt;

&lt;p&gt;In my next post we will take what we learned here and implement a sortable list. Follow along for more drag and drop and other Ember tutorials.&lt;/p&gt;

&lt;p&gt;For more drag and drop event information visit the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API"&gt;MDN docs&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>ember</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
