{"id":1874,"date":"2018-06-12T15:39:03","date_gmt":"2018-06-12T12:39:03","guid":{"rendered":"https:\/\/imagga.com\/blog\/?p=1874"},"modified":"2019-06-06T15:24:02","modified_gmt":"2019-06-06T12:24:02","slug":"autotagging-uploads-with-nodejs","status":"publish","type":"post","link":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/","title":{"rendered":"Create Autotagging Uploads with NodeJS using Image Recognition API"},"content":{"rendered":"<div class=\"wpb-content-wrapper\"><p>[vc_row][vc_column width=&#8221;2\/3&#8243;][vc_column_text]<br \/>\nApplications these days are visual. There&#8217;s no denying it. Applications these days are also social. Combine those two and, inevitably, you are going to need to enable your users to upload images and share them, either on their own or as part of larger creations.<br \/>\nWith the sharing of images comes the desire to organize and tag them. Tagging images come with a litany of benefits, including:<\/p>\n<ul>\n<li>Allowing other users to search for specific categories of images<\/li>\n<li>Automatically labeling images for screen-readers and other accessibility tools<\/li>\n<li>Easy sorting and organization of images into folders or trees<\/li>\n<\/ul>\n<p>What we&#8217;re building today is a widget that you could easily embed within your own applications. It will take an image selected by the user, upload it to the Imagga servers and tag it, then automatically recommend the top tags for use within your app. The user will still be able to edit and customize the tags for an image, though their selections will be limited to the larger list suggested by Imagga to prevent spamming.<\/p>\n<p>In your own development, you might implement a widget like this as part of a social networking platform, such as a forum or image sharing service. Anytime users are able to upload and categorize their own images, it&#8217;s important to both streamline that process for them as well as put restrictions around those categorizations so that they are accurate and not misleading to your other users.<\/p>\n<h3 id=\"source-code\">Source code<\/h3>\n<p>If you&#8217;re merely interested in an overview of how an auto-tagging system like this can be built with Imagga, feel free to skip to the next section. If you&#8217;d like to follow along more closely, however, <strong>you can download the code from the sidebar to the right<\/strong> and use git tags to match the code with each stage. For example, if the stage is <strong><code>index-and-api-routes<\/code><\/strong>, just type in <strong><code>git checkout index-and-api-routes<\/code><\/strong> into your terminal to see the code at that stage. If you get stuck or make changes, you can always use <strong><code>get reset HEAD --hard<\/code><\/strong> to return to the base code for that stage or <strong><code>git checkout master<\/code><\/strong> to return to the completed code.<\/p>\n<p>If you choose to also build and run the code yourself, you will need to get an Imagga API key and secret and add them to a <code>.env<\/code> file at the root of the code, like so:<\/p>\n<p><strong>API_KEY=MY_KEY_HERE<\/strong><br \/>\n<strong>API_SECRET=MY_SECRET_HERE<\/strong><\/p>\n<p>You&#8217;ll also need to run an <strong><code>npm install<\/code><\/strong> within the repo to get the dependencies we need to run the application.<\/p>\n<h2 id=\"how-does-the-tagging-api-work\">How does the tagging API work<\/h2>\n<p><strong>Git tag: <code>index-and-api-routes<\/code><\/strong><\/p>\n<p>Before we get started, we need to understand how to use the Imagga tagging API. The API at <strong><code>https:\/\/api.imagga.com\/v2\/tags<\/code><\/strong> takes a <strong><code>GET<\/code><\/strong> request with a specified image, and then returns an array of tags, sorted by confidence. For example, if we ask it to analyze this gorgeous mountain vista:<\/p>\n<div class=\"figure\">\n<p><img src=\"https:\/\/farm2.staticflickr.com\/1913\/45466846601_48920a6f37_z_d.jpg\" alt=\"Mountains\" \/><\/p>\n<\/div>\n<h2>We end up with a list of tags looking like this:<\/h2>\n<div class=\"sourceCode\">\n<pre class=\"sourceCode javascript\"><code class=\"sourceCode javascript\"><span class=\"op\">{<\/span>\r\n    <span class=\"st\">\"result\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n        <span class=\"st\">\"tags\"<\/span><span class=\"op\">:<\/span> [\r\n            <span class=\"op\">{<\/span>\r\n                <span class=\"st\">\"confidence\"<\/span><span class=\"op\">:<\/span> <span class=\"fl\">76.4135513305664<\/span><span class=\"op\">,<\/span>\r\n                <span class=\"st\">\"tag\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n                    <span class=\"st\">\"en\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"mountain\"<\/span>\r\n                <span class=\"op\">}<\/span>\r\n            <span class=\"op\">},<\/span>\r\n            <span class=\"op\">{<\/span>\r\n                <span class=\"st\">\"confidence\"<\/span><span class=\"op\">:<\/span> <span class=\"fl\">69.7975997924805<\/span><span class=\"op\">,<\/span>\r\n                <span class=\"st\">\"tag\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n                    <span class=\"st\">\"en\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"highland\"<\/span>\r\n                <span class=\"op\">}<\/span>\r\n            <span class=\"op\">},<\/span>\r\n            <span class=\"op\">{<\/span>\r\n                <span class=\"st\">\"confidence\"<\/span><span class=\"op\">:<\/span> <span class=\"fl\">54.8374099731445<\/span><span class=\"op\">,<\/span>\r\n                <span class=\"st\">\"tag\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n                    <span class=\"st\">\"en\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"mountains\"<\/span>\r\n                <span class=\"op\">}<\/span>\r\n            <span class=\"op\">},<\/span>\r\n            <span class=\"op\">{<\/span>\r\n                <span class=\"st\">\"confidence\"<\/span><span class=\"op\">:<\/span> <span class=\"fl\">54.5085144042969<\/span><span class=\"op\">,<\/span>\r\n                <span class=\"st\">\"tag\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n                    <span class=\"st\">\"en\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"landscape\"<\/span>\r\n                <span class=\"op\">}<\/span>\r\n            <span class=\"op\">},<\/span>\r\n            <span class=\"op\">{<\/span>\r\n                <span class=\"st\">\"confidence\"<\/span><span class=\"op\">:<\/span> <span class=\"fl\">38.0158271789551<\/span><span class=\"op\">,<\/span>\r\n                <span class=\"st\">\"tag\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n                    <span class=\"st\">\"en\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"sky\"<\/span>\r\n                <span class=\"op\">}<\/span>\r\n            <span class=\"op\">},<\/span>\r\n            <span class=\"co\">\/* ... More tags here ... *\/<\/span>\r\n        ]\r\n    <span class=\"op\">},<\/span>\r\n    <span class=\"st\">\"status\"<\/span><span class=\"op\">:<\/span> <span class=\"op\">{<\/span>\r\n        <span class=\"st\">\"text\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"\"<\/span><span class=\"op\">,<\/span>\r\n        <span class=\"st\">\"type\"<\/span><span class=\"op\">:<\/span> <span class=\"st\">\"success\"<\/span>\r\n    <span class=\"op\">}<\/span>\r\n<span class=\"op\">}<\/span><\/code><\/pre>\n<\/div>\n<p>The tagging API accepts one of two methods for identifying the image you want tagged: <strong><code>image_url<\/code><\/strong> and <strong><code>image_upload_id<\/code><\/strong>. If we use <strong><code>image_url<\/code><\/strong>, we can point the API to any image hosted on a publicly accessible web address and tag it, which is exactly what we did for the mountain image above. This is most helpful if the user is attaching an image already uploaded onto the internet somewhere.<\/p>\n<p>For most applications, though, we want to allow the user to upload their own images, in which case we need to first understand another Imagga API, the <strong><code>uploads<\/code><\/strong> endpoint.<\/p>\n<h2 id=\"take-a-look-at-a-simple-upload\">Take a look at a simple upload<\/h2>\n<p><strong>Git Tag: <code>upload-and-tag<\/code><\/strong><\/p>\n<p>There are two ways to handle tagging uploads with Imagga. In v1 of the API, it was a two-step process, requiring us first to upload the image, than use the returned <strong><code>upload_id<\/code><\/strong> to retrieve the tags. With v2, we now recommend you upload and tag the image all in one request, using the <strong><code>POST<\/code><\/strong> method to our tagging API. As such, that&#8217;s the method we&#8217;ll use here, but if you&#8217;re still using v1 and want to see an example of how the two-step process might work, check out the git tag <strong><code>upload-and-tag-v1<\/code><\/strong> for an example.<\/p>\n<blockquote><p><strong>Important note<\/strong>: However you handle uploads, it&#8217;s important to know that Imagga does not permanently store the images you upload. For security purposes, they only remain on the Imagga server for 24 hours, so if you&#8217;re using the two-step approach you&#8217;ll want to ensure you download and store the tags for your uploads within that time period. If you need to have the images removed immediately, you can use the upload_id and a DELETE call to the API as well.<\/p><\/blockquote>\n<p>For our sake, however, let&#8217;s just take a look at the simplified one-step approach. Our frontend is pretty generic (our demo uses FilePond for simplicity, but any file upload script will work), so let&#8217;s focus on the Node.JS backend:<\/p>\n<div class=\"sourceCode\">\n<pre class=\"sourceCode javascript\"><code class=\"sourceCode javascript\"><span class=\"va\">apiRouter<\/span>.<span class=\"at\">post<\/span>(<span class=\"st\">'\/tag'<\/span><span class=\"op\">,<\/span> <span class=\"kw\">function<\/span> (req<span class=\"op\">,<\/span> res) <span class=\"op\">{<\/span>\r\n  <span class=\"co\">\/\/ Get the image field from the POST request<\/span>\r\n  <span class=\"kw\">let<\/span> image <span class=\"op\">=<\/span> <span class=\"va\">req<\/span>.<span class=\"va\">files<\/span>.<span class=\"at\">image<\/span><span class=\"op\">;<\/span>\r\n  <span class=\"cf\">if<\/span> (<span class=\"op\">!<\/span>image) <span class=\"op\">{<\/span>\r\n    <span class=\"va\">res<\/span>.<span class=\"at\">writeHead<\/span>(<span class=\"dv\">300<\/span><span class=\"op\">,<\/span> <span class=\"op\">{<\/span><span class=\"st\">'Content-type'<\/span><span class=\"op\">:<\/span> <span class=\"st\">'text\/javascript'<\/span><span class=\"op\">}<\/span>)\r\n    <span class=\"va\">res<\/span>.<span class=\"at\">end<\/span>(<span class=\"va\">JSON<\/span>.<span class=\"at\">stringify<\/span>(<span class=\"op\">{<\/span><span class=\"st\">'status'<\/span><span class=\"op\">:<\/span> <span class=\"st\">'failed'<\/span><span class=\"op\">,<\/span> <span class=\"st\">'error'<\/span><span class=\"op\">:<\/span> <span class=\"st\">'no image specified'<\/span><span class=\"op\">}<\/span>))\r\n    <span class=\"cf\">return<\/span>\r\n  <span class=\"op\">}<\/span>\r\n\r\n  api\r\n    .<span class=\"at\">tags<\/span>(<span class=\"op\">{<\/span>\r\n      <span class=\"dt\">image<\/span><span class=\"op\">:<\/span> <span class=\"va\">image<\/span>.<span class=\"at\">data<\/span> <span class=\"co\">\/\/ Pass pure image buffer to API<\/span>\r\n    <span class=\"op\">}<\/span>)\r\n    .<span class=\"at\">then<\/span>(\r\n      <span class=\"kw\">function<\/span> (tags) <span class=\"op\">{<\/span>\r\n        <span class=\"kw\">let<\/span> data <span class=\"op\">=<\/span> <span class=\"op\">{<\/span>\r\n          <span class=\"dt\">tags<\/span><span class=\"op\">:<\/span> tags\r\n        <span class=\"op\">}<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">writeHead<\/span>(<span class=\"dv\">200<\/span><span class=\"op\">,<\/span> <span class=\"op\">{<\/span><span class=\"st\">'Content-type'<\/span><span class=\"op\">:<\/span> <span class=\"st\">'text\/javascript'<\/span><span class=\"op\">}<\/span>)<span class=\"op\">;<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">write<\/span>(<span class=\"va\">JSON<\/span>.<span class=\"at\">stringify<\/span>(data))<span class=\"op\">;<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">end<\/span>()<span class=\"op\">;<\/span>\r\n      <span class=\"op\">},<\/span>\r\n      <span class=\"kw\">function<\/span> (err) <span class=\"op\">{<\/span>\r\n        <span class=\"va\">console<\/span>.<span class=\"at\">warn<\/span>(<span class=\"st\">'Error getting tags'<\/span><span class=\"op\">,<\/span> err)<span class=\"op\">;<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">writeHead<\/span>(<span class=\"dv\">500<\/span><span class=\"op\">,<\/span> <span class=\"op\">{<\/span><span class=\"st\">'Content-type'<\/span><span class=\"op\">:<\/span> <span class=\"st\">'text\/javascript'<\/span><span class=\"op\">}<\/span>)<span class=\"op\">;<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">write<\/span>(<span class=\"va\">JSON<\/span>.<span class=\"at\">stringify<\/span>(err))<span class=\"op\">;<\/span>\r\n        <span class=\"va\">res<\/span>.<span class=\"at\">end<\/span>()<span class=\"op\">;<\/span>\r\n      <span class=\"op\">}<\/span>\r\n    )<span class=\"op\">;<\/span>\r\n<span class=\"op\">}<\/span>)<span class=\"op\">;<\/span><\/code><\/pre>\n<\/div>\n<p>As a reminder, for the full file context, check out the <a href=\"http:\/\/www.example.com\/repo\">repo<\/a> and use the tag <strong><code>upload-and-tag<\/code><\/strong>.<\/p>\n<p>So let&#8217;s walk through the code. First, we have an express router that takes a <strong><code>POST<\/code><\/strong> request to <strong><code>\/tags<\/code><\/strong> with an image file upload. Our middleware (<strong><code>express-fileupload<\/code><\/strong>) has made our files easily accessible on the <strong><code>req.files<\/code><\/strong> hash, so all we have to do is grab that data and pass it along to our <strong><code>tags<\/code><\/strong> handler. For cleanliness, we&#8217;ve abstracted the specifics of the HTTP requests to a separate file in <strong><code>api-request.js<\/code><\/strong>, but you can see the flow here.<\/p>\n<p>Then, once our request returns with the tags, we simply pass that back on out to the frontend. As we noted above, the response format is exactly the same, so our frontend handler can be exactly the same regardless of whether this is a direct upload or an image url.<\/p>\n<p><img class=\"alignnone size-full wp-image-1875\" src=\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2018\/11\/upload-and-tag.png\" alt=\"\" width=\"690\" height=\"457\" \/><\/p>\n<h2 id=\"connecting-to-an-auto-tag-dropdown\">Connecting to an auto-tag dropdown<\/h2>\n<p><strong>Git tag: <code>preview-and-autotag<\/code><\/strong><\/p>\n<p>Having a raw display of tags is helpful for debugging and development, but it is hardly the kind of user experience we want for our actual applications, so let&#8217;s take a look at connecting these tags to something more user-friendly.<\/p>\n<p>For this, we&#8217;re going to utilize a tagging library called <a href=\"https:\/\/github.com\/yairEO\/tagify\">tagify<\/a> which turns our text input into a tag field. The flow will be that the user uploads an image, the API passes that on to Imagga and retrieves the tags, and then our widget will allow the user to accept or change the suggested tags. Any tag marked with 60% confidence or higher will be auto-suggested (or the top 3 tags, whichever is greater), and the user will be allowed to add more, but only from the list that Imagga returns. This ensures that while the user can correct or edit the tagging, they cannot add any completely inaccurate tags that might mislead other users on our site.<\/p>\n<p>Our code for the API remains the same as before, so let&#8217;s take a look at the frontend code that handles the response:<\/p>\n<div class=\"sourceCode\">\n<pre class=\"sourceCode javascript\"><code class=\"sourceCode javascript\"><span class=\"kw\">var<\/span> tagify\r\n  <span class=\"op\">,<\/span> imgFile<span class=\"op\">;<\/span>\r\n<span class=\"kw\">var<\/span> showResults <span class=\"op\">=<\/span> <span class=\"kw\">function<\/span> (tags) <span class=\"op\">{<\/span>\r\n  <span class=\"kw\">var<\/span> container <span class=\"op\">=<\/span> <span class=\"va\">document<\/span>.<span class=\"at\">getElementById<\/span>(<span class=\"st\">'output'<\/span>)\r\n    <span class=\"op\">,<\/span> preview <span class=\"op\">=<\/span> <span class=\"va\">document<\/span>.<span class=\"at\">getElementById<\/span>(<span class=\"st\">'preview'<\/span>)\r\n    <span class=\"op\">,<\/span> tagEl <span class=\"op\">=<\/span> <span class=\"va\">document<\/span>.<span class=\"at\">getElementById<\/span>(<span class=\"st\">'tags-json'<\/span>)\r\n    <span class=\"op\">,<\/span> tagInput <span class=\"op\">=<\/span> <span class=\"va\">document<\/span>.<span class=\"at\">getElementById<\/span>(<span class=\"st\">'tags'<\/span>)\r\n    <span class=\"op\">,<\/span> tagList <span class=\"op\">=<\/span> <span class=\"at\">getTagList<\/span>(tags)<span class=\"op\">;<\/span>\r\n\r\n  <span class=\"co\">\/\/ Render the raw JSON response for debugging<\/span>\r\n  <span class=\"va\">tagEl<\/span>.<span class=\"at\">innerHTML<\/span> <span class=\"op\">=<\/span> <span class=\"va\">JSON<\/span>.<span class=\"at\">stringify<\/span>(tags<span class=\"op\">,<\/span> <span class=\"kw\">null<\/span><span class=\"op\">,<\/span> <span class=\"dv\">2<\/span>)<span class=\"op\">;<\/span>\r\n\r\n  <span class=\"cf\">if<\/span> (tagify) <span class=\"op\">{<\/span>\r\n    <span class=\"co\">\/\/ Have already initialized tagify, just update with new tags<\/span>\r\n    <span class=\"va\">tagify<\/span>.<span class=\"at\">removeAllTags<\/span>()<span class=\"op\">;<\/span>\r\n    <span class=\"va\">tagify<\/span>.<span class=\"va\">settings<\/span>.<span class=\"at\">whitelist<\/span> <span class=\"op\">=<\/span> <span class=\"va\">tagList<\/span>.<span class=\"at\">all<\/span><span class=\"op\">;<\/span>\r\n  <span class=\"op\">}<\/span> <span class=\"cf\">else<\/span> <span class=\"op\">{<\/span>\r\n    <span class=\"co\">\/\/ Initialize new tagify and set whitelist<\/span>\r\n    tagify <span class=\"op\">=<\/span> <span class=\"kw\">new<\/span> <span class=\"at\">Tagify<\/span>(\r\n      tagInput<span class=\"op\">,<\/span>\r\n      <span class=\"op\">{<\/span>\r\n        <span class=\"dt\">whitelist<\/span><span class=\"op\">:<\/span> <span class=\"va\">tagList<\/span>.<span class=\"at\">all<\/span><span class=\"op\">,<\/span>\r\n        <span class=\"dt\">enforceWhitelist<\/span><span class=\"op\">:<\/span> <span class=\"kw\">true<\/span>\r\n      <span class=\"op\">}<\/span>\r\n    )<span class=\"op\">;<\/span>\r\n  <span class=\"op\">}<\/span>\r\n  <span class=\"va\">tagify<\/span>.<span class=\"at\">addTags<\/span>(<span class=\"va\">tagList<\/span>.<span class=\"at\">auto<\/span>)<span class=\"op\">;<\/span>\r\n\r\n  <span class=\"cf\">if<\/span> (imgFile) <span class=\"op\">{<\/span>\r\n    <span class=\"va\">preview<\/span>.<span class=\"at\">src<\/span> <span class=\"op\">=<\/span> <span class=\"va\">URL<\/span>.<span class=\"at\">createObjectURL<\/span>(<span class=\"va\">imgFile<\/span>.<span class=\"at\">file<\/span>)<span class=\"op\">;<\/span>\r\n  <span class=\"op\">}<\/span>\r\n  <span class=\"va\">container<\/span>.<span class=\"va\">classList<\/span>.<span class=\"at\">remove<\/span>(<span class=\"st\">'hidden'<\/span>)\r\n<span class=\"op\">};<\/span>\r\n\r\n<span class=\"kw\">var<\/span> threshold <span class=\"op\">=<\/span> <span class=\"dv\">60<\/span><span class=\"op\">;<\/span>\r\n<span class=\"kw\">var<\/span> getTagList <span class=\"op\">=<\/span> <span class=\"kw\">function<\/span> (tags) <span class=\"op\">{<\/span>\r\n  <span class=\"kw\">var<\/span> list <span class=\"op\">=<\/span> <span class=\"op\">{<\/span>\r\n    <span class=\"dt\">auto<\/span><span class=\"op\">:<\/span> []<span class=\"op\">,<\/span>\r\n    <span class=\"dt\">all<\/span><span class=\"op\">:<\/span> []\r\n  <span class=\"op\">}<\/span>\r\n  <span class=\"cf\">for<\/span> (<span class=\"kw\">var<\/span> i <span class=\"op\">=<\/span> <span class=\"dv\">0<\/span><span class=\"op\">,<\/span> ii <span class=\"op\">=<\/span> <span class=\"va\">tags<\/span>.<span class=\"at\">length<\/span><span class=\"op\">;<\/span> i <span class=\"op\">&lt;<\/span> ii<span class=\"op\">;<\/span> i<span class=\"op\">++<\/span>) <span class=\"op\">{<\/span>\r\n    <span class=\"kw\">var<\/span> tag <span class=\"op\">=<\/span> tags[i]\r\n      <span class=\"op\">,<\/span> t <span class=\"op\">=<\/span> <span class=\"va\">tag<\/span>.<span class=\"va\">tag<\/span>.<span class=\"at\">en<\/span><span class=\"op\">;<\/span>\r\n\r\n    <span class=\"co\">\/\/ Add first three tags to 'auto-suggest' array, along with any<\/span>\r\n    <span class=\"co\">\/\/ others over confidence threshold<\/span>\r\n    <span class=\"cf\">if<\/span> (<span class=\"va\">list<\/span>.<span class=\"va\">auto<\/span>.<span class=\"at\">length<\/span> <span class=\"op\">&lt;<\/span> <span class=\"dv\">3<\/span> <span class=\"op\">||<\/span> <span class=\"va\">tag<\/span>.<span class=\"at\">confidence<\/span> <span class=\"op\">&gt;<\/span> threshold) <span class=\"op\">{<\/span>\r\n      <span class=\"va\">list<\/span>.<span class=\"va\">auto<\/span>.<span class=\"at\">push<\/span>(t)<span class=\"op\">;<\/span>\r\n    <span class=\"op\">}<\/span>\r\n    <span class=\"va\">list<\/span>.<span class=\"va\">all<\/span>.<span class=\"at\">push<\/span>(t)<span class=\"op\">;<\/span>\r\n  <span class=\"op\">}<\/span>\r\n  <span class=\"cf\">return<\/span> list<span class=\"op\">;<\/span>\r\n<span class=\"op\">}<\/span><\/code><\/pre>\n<\/div>\n<p>Let&#8217;s walk through this from the top. <strong><code>showResults<\/code><\/strong> receives the tags from the Imagga API and immediately outputs the raw results into our <strong><code>pre<\/code><\/strong> tag for easy viewing. Again, we obviously wouldn&#8217;t include this in a final application, but it can be helpful during development, especially when we want to test our auto-suggest dropdown here shortly.<\/p>\n<p>Along with outputting the raw results, our next task before creating the auto-suggest input is to convert the list from Imagga into something our tagging plugin can understand. For this, we use <strong><code>getTagList<\/code><\/strong>. There we loop through all the suggested tags, creating two arrays: an <strong><code>auto<\/code><\/strong> array with the first three tags along with any others that are above the confidence threshold (60% in this case) and an <strong><code>all<\/code><\/strong> array which we&#8217;ll use for the suggestions dropdown.<\/p>\n<p>From there, we simply pass those along to <strong><code>tagify<\/code><\/strong>, either updating an existing input (if this isn&#8217;t the first image we&#8217;ve uploaded) or creating a new one. Finally, for a better user experience, we render the image the user uploaded in the <strong><code>preview<\/code><\/strong> element so they can be assured everything was processed correctly.<\/p>\n<p>Go ahead and upload the mountain image we used before (you can download it <a href=\"https:\/\/www.flickr.com\/photos\/159610055@N08\/45466846601\/in\/photolist-2bb9JwC-2b9Usmq-2ccDR7Y-2aTsgXx-2chdS84-2bYGxKK-2cgKtsi-2c1Ci8W-29dST1Y-MHrZnr-29vCTiY-2ccPUDY-MTZgPc-29reA5j-NwmQfX-2aTC5br-2c4wFvq-2c1phZV-29sQr5j-2cf2NLZ-2bPJCAg-2aKamGy-MDnZjx-29vCSqf-Q3M4ny-2c7AC5S-2aqg5QX-MZc4Np-2baY9SJ-2ahiVuy-2cbegAU-Nwzjak-2bTmWGC-Nsh8wK-2ccctL3-29wdUPq-2aXdtpU-PZ5SWw-2azB4tK-Q9wfK7-29okE3L-28FwgGh-NiGTVa-NvWaxK-29vqkfJ-2aEhfGo-29mhyLm-2c81Leu-2awuFdH-2c2HqRV\">here<\/a>), and take a look at how this all comes together. Once it&#8217;s uploaded, you should see it previewed on the right, along with three recommended tags: mountain, highland, and landscape.<\/p>\n<p><img class=\"alignnone size-medium wp-image-1876\" src=\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2018\/11\/preview-and-autotag-780x600.png\" alt=\"\" width=\"780\" height=\"600\" srcset=\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2018\/11\/preview-and-autotag-780x600.png 780w, https:\/\/imagga.com\/blog\/wp-content\/uploads\/2018\/11\/preview-and-autotag-768x591.png 768w, https:\/\/imagga.com\/blog\/wp-content\/uploads\/2018\/11\/preview-and-autotag.png 906w\" sizes=\"(max-width: 780px) 100vw, 780px\" \/><\/p>\n<p>Now try adding some tags that are included farther down in the suggestions, such as &#8220;travel&#8221; or &#8220;peaceful.&#8221; Both of these should auto-complete as you type, just hit <strong><code>tab<\/code><\/strong> to add them to the list. Remember though, we want to prevent users from adding tags that are completely inaccurate, so now try typing something not in the list, such as &#8220;ocean.&#8221; You&#8217;ll see that not only is it not part of the suggestion dropdown, if you hit <strong><code>enter<\/code><\/strong> to try to add it, it will automatically be removed.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>Today we&#8217;ve covered how the Imagga tagging and upload APIs work and how you can use them together to implement an auto-tagging widget within your NodeJS projects. Hopefully you can see how quickly and easily you can integrate them to enhance your users&#8217; experiences and streamline your applications. Got a question or a suggestion for what we should build next? Tell us in the comments, we&#8217;d love to hear from you!<\/p>\n<h2 id=\"libraries-used\">Libraries used<\/h2>\n<ul>\n<li><a href=\"https:\/\/docs.imagga.com\/\">Imagga API Documentation<\/a> &#8211; For further reading about the Imagga API<\/li>\n<li><a href=\"https:\/\/pqina.nl\/filepond\/\">FilePond<\/a> &#8211; For easy uploading in Javascript<\/li>\n<li><a href=\"https:\/\/github.com\/yairEO\/tagify\">Tagify<\/a> &#8211; For tagging input<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/express-fileupload\">express-fileupload<\/a> &#8211; For parsing uploads in Node.JS<\/li>\n<\/ul>\n<p>[\/vc_column_text][\/vc_column]<br \/>\n[vc_column width=&#8221;1\/3&#8243;][vc_column_text]<\/p>\n<p><!-- Begin Mailchimp Signup Form --><\/p>\n<style type=\"text\/css\">\n#mc-embedded-subscribe-form input[type=checkbox]{display: inline; width: auto;margin-right: 10px;}<br \/>#mergeRow-gdpr {margin-top: 20px;}<br \/>#mergeRow-gdpr fieldset label {font-weight: normal;}<br \/>#mc-embedded-subscribe-form .mc_fieldset{border:none;min-height: 0px;padding-bottom:0px;}<br \/><\/style>\n<div id=\"mc_embed_signup\" style=\"background-color: #e7e7e7; clear: left; font: 14px Helvetica,Arial,sans-serif; border: 1px solid #ccc; padding: 0 1rem 1rem;\">\n<form id=\"mc-embedded-subscribe-form\" class=\"validate\" action=\"https:\/\/imagga.us2.list-manage.com\/subscribe\/post?u=b1ac9881f9fa5cda50097f7a1&amp;id=c94e96024a\" method=\"post\" name=\"mc-embedded-subscribe-form\" novalidate=\"\" target=\"_blank\">\n<div id=\"mc_embed_signup_scroll\">\n<h5 style=\"margin: 1rem 0; color: #000;\">Download Free Auto Tagging Uploads with Node.Js Files<\/h5>\n<div class=\"mc-field-group\"><label style=\"font-size: 0.9rem; color: #05193c;\" for=\"mce-FNAME\">First Name <\/label><br \/>\n<input id=\"mce-FNAME\" class=\"\" style=\"width: 90%; margin: 0 0 1rem 0;\" name=\"FNAME\" type=\"text\" value=\"\" \/><\/div>\n<div class=\"mc-field-group\"><label style=\"font-size: 0.9rem; color: #05193c;\" for=\"mce-LNAME\">Last Name <\/label><br \/>\n<input id=\"mce-LNAME\" class=\"\" style=\"width: 90%; margin: 0 0 1rem 0;\" name=\"LNAME\" type=\"text\" value=\"\" \/><\/div>\n<div class=\"mc-field-group\"><label style=\"font-size: 0.9rem; color: #05193c;\" for=\"mce-EMAIL\">Email Address <span style=\"color: red;\">*<\/span> <\/label><input id=\"mce-EMAIL\" class=\"required email\" style=\"width: 90%; margin: 0 0 1rem 0;\" name=\"EMAIL\" type=\"email\" value=\"\" \/><\/div>\n<div id=\"mergeRow-gdpr\" class=\"mergeRow gdpr-mergeRow content__gdprBlock mc-field-group\">\n<div class=\"content__gdpr\">\n<h5 style=\"font-size: 0.9rem; color: #000;\">Marketing Permissions For Imagga<\/h5>\n<fieldset class=\"mc_fieldset gdprRequired mc-field-group\" style=\"margin-bottom: 1rem; border: none;\" name=\"interestgroup_field\"><label class=\"checkbox subfield\" for=\"gdpr_4461\"><input id=\"gdpr_4461\" class=\"av-checkbox \" style=\"height: 18px; display: inline-block;\" name=\"gdpr[4461]\" type=\"checkbox\" value=\"Y\" \/><span style=\"font-size: 0.9rem; color: #05193c;\">Email<\/span><\/label><br \/>\n<label class=\"checkbox subfield\" for=\"gdpr_4465\"><input id=\"gdpr_4465\" class=\"av-checkbox \" style=\"height: 18px; display: inline-block;\" name=\"gdpr[4465]\" type=\"checkbox\" value=\"Y\" \/><span style=\"font-size: 0.9rem; color: #05193c;\">Direct Mail<\/span><\/label><br \/>\n<label class=\"checkbox subfield\" for=\"gdpr_4469\"><input id=\"gdpr_4469\" class=\"av-checkbox \" style=\"height: 18px; display: inline-block;\" name=\"gdpr[4469]\" type=\"checkbox\" value=\"Y\" \/><span style=\"font-size: 0.9rem; color: #05193c;\">Customized Online Advertising<\/span><\/label><\/fieldset>\n<p style=\"font-size: 0.7rem; font-weight: 400; margin: 0 0 0.6rem 0; color: #747980;\">We are always concious about sending a lot of emails, so our commitment is that we will send only when there is something interesting or free knowledge that we would like to share with you. If you feel like we are not living up to that expectation you can unsubscribe at any time by clicking the link in the footer of our emails.<\/p>\n<\/div>\n<\/div>\n<div id=\"mce-responses\" class=\"clear\">\n<div id=\"mce-error-response\" class=\"response\" style=\"display: none;\"><\/div>\n<div id=\"mce-success-response\" class=\"response\" style=\"display: none;\"><\/div>\n<\/div>\n<p><!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--><\/p>\n<div style=\"position: absolute; left: -5000px;\" aria-hidden=\"true\"><input tabindex=\"-1\" name=\"b_b1ac9881f9fa5cda50097f7a1_c94e96024a\" type=\"text\" value=\"\" \/><\/div>\n<div class=\"clear\"><input id=\"mc-embedded-subscribe\" class=\"button\" style=\"background-color: #2c3945; color: #fff;\" name=\"subscribe\" type=\"submit\" value=\"Download Code File\" \/><\/div>\n<\/div>\n<\/form>\n<\/div>\n<p><script type=\"text\/javascript\" src=\"\/\/s3.amazonaws.com\/downloads.mailchimp.com\/js\/mc-validate.js\"><\/script><script type=\"text\/javascript\">(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';fnames[3]='ADDRESS';ftypes[3]='address';fnames[4]='PHONE';ftypes[4]='phone';}(jQuery));var $mcj = jQuery.noConflict(true);<\/script><br \/>\n<!--End mc_embed_signup--><\/p>\n<p>[\/vc_column_text][\/vc_column][\/vc_row]<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>[vc_row][vc_column width=&#8221;2\/3&#8243;][vc_column_text] Applications these days are visual. There&#8217;s no denying it. Applications these days are also social. Combine those two [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":1873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,211],"tags":[129,143,202,203,204,205,206],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v17.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog\" \/>\n<meta property=\"og:description\" content=\"[vc_row][vc_column width=&#8221;2\/3&#8243;][vc_column_text] Applications these days are visual. There&#8217;s no denying it. Applications these days are also social. Combine those two [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/\" \/>\n<meta property=\"og:site_name\" content=\"Imagga Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/imagga\/\" \/>\n<meta property=\"article:published_time\" content=\"2018-06-12T12:39:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-06-06T12:24:02+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<meta name=\"twitter:creator\" content=\"@imagga\" \/>\n<meta name=\"twitter:site\" content=\"@imagga\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alex Vantson\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/imagga.com\/blog\/#organization\",\"name\":\"Imagga\",\"url\":\"https:\/\/imagga.com\/blog\/\",\"sameAs\":[\"https:\/\/www.facebook.com\/imagga\/\",\"https:\/\/twitter.com\/imagga\",\"https:\/\/www.linkedin.com\/company\/imagga\/\",\"https:\/\/twitter.com\/imagga\"],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/imagga.com\/blog\/#logo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/logo_white_blog.svg\",\"contentUrl\":\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/logo_white_blog.svg\",\"width\":\"27\",\"height\":\"29\",\"caption\":\"Imagga\"},\"image\":{\"@id\":\"https:\/\/imagga.com\/blog\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/imagga.com\/blog\/#website\",\"url\":\"https:\/\/imagga.com\/blog\/\",\"name\":\"Imagga Blog\",\"description\":\"Image recognition in the cloud\",\"publisher\":{\"@id\":\"https:\/\/imagga.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/imagga.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg\",\"contentUrl\":\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg\",\"width\":1920,\"height\":1080},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage\",\"url\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/\",\"name\":\"Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog\",\"isPartOf\":{\"@id\":\"https:\/\/imagga.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage\"},\"datePublished\":\"2018-06-12T12:39:03+00:00\",\"dateModified\":\"2019-06-06T12:24:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/imagga.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create Autotagging Uploads with NodeJS using Image Recognition API\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage\"},\"author\":{\"@id\":\"https:\/\/imagga.com\/blog\/#\/schema\/person\/387e81bf6c4ad0798a7d889e6eac4aa2\"},\"headline\":\"Create Autotagging Uploads with NodeJS using Image Recognition API\",\"datePublished\":\"2018-06-12T12:39:03+00:00\",\"dateModified\":\"2019-06-06T12:24:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage\"},\"wordCount\":1651,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/imagga.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg\",\"keywords\":[\"auto tagging\",\"application\",\"nodejs\",\"goland\",\"reactjs\",\"vscode\",\"environmental variables\"],\"articleSection\":[\"Tech Insider\",\"Code Hacks\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/imagga.com\/blog\/#\/schema\/person\/387e81bf6c4ad0798a7d889e6eac4aa2\",\"name\":\"Alex Vantson\",\"url\":\"https:\/\/imagga.com\/blog\/author\/mrvdot\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/","og_locale":"en_US","og_type":"article","og_title":"Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog","og_description":"[vc_row][vc_column width=&#8221;2\/3&#8243;][vc_column_text] Applications these days are visual. There&#8217;s no denying it. Applications these days are also social. Combine those two [&hellip;]","og_url":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/","og_site_name":"Imagga Blog","article_publisher":"https:\/\/www.facebook.com\/imagga\/","article_published_time":"2018-06-12T12:39:03+00:00","article_modified_time":"2019-06-06T12:24:02+00:00","og_image":[{"width":1920,"height":1080,"url":"http:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg","type":"image\/jpeg"}],"twitter_card":"summary","twitter_creator":"@imagga","twitter_site":"@imagga","twitter_misc":{"Written by":"Alex Vantson","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/imagga.com\/blog\/#organization","name":"Imagga","url":"https:\/\/imagga.com\/blog\/","sameAs":["https:\/\/www.facebook.com\/imagga\/","https:\/\/twitter.com\/imagga","https:\/\/www.linkedin.com\/company\/imagga\/","https:\/\/twitter.com\/imagga"],"logo":{"@type":"ImageObject","@id":"https:\/\/imagga.com\/blog\/#logo","inLanguage":"en-US","url":"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/logo_white_blog.svg","contentUrl":"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/logo_white_blog.svg","width":"27","height":"29","caption":"Imagga"},"image":{"@id":"https:\/\/imagga.com\/blog\/#logo"}},{"@type":"WebSite","@id":"https:\/\/imagga.com\/blog\/#website","url":"https:\/\/imagga.com\/blog\/","name":"Imagga Blog","description":"Image recognition in the cloud","publisher":{"@id":"https:\/\/imagga.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/imagga.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage","inLanguage":"en-US","url":"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg","contentUrl":"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg","width":1920,"height":1080},{"@type":"WebPage","@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage","url":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/","name":"Create Autotagging Uploads with NodeJS using Image Recognition API - Imagga Blog","isPartOf":{"@id":"https:\/\/imagga.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage"},"datePublished":"2018-06-12T12:39:03+00:00","dateModified":"2019-06-06T12:24:02+00:00","breadcrumb":{"@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/imagga.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create Autotagging Uploads with NodeJS using Image Recognition API"}]},{"@type":"Article","@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#article","isPartOf":{"@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage"},"author":{"@id":"https:\/\/imagga.com\/blog\/#\/schema\/person\/387e81bf6c4ad0798a7d889e6eac4aa2"},"headline":"Create Autotagging Uploads with NodeJS using Image Recognition API","datePublished":"2018-06-12T12:39:03+00:00","dateModified":"2019-06-06T12:24:02+00:00","mainEntityOfPage":{"@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#webpage"},"wordCount":1651,"commentCount":0,"publisher":{"@id":"https:\/\/imagga.com\/blog\/#organization"},"image":{"@id":"https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#primaryimage"},"thumbnailUrl":"https:\/\/imagga.com\/blog\/wp-content\/uploads\/2017\/04\/Node_Js_Imagga_Article.jpg","keywords":["auto tagging","application","nodejs","goland","reactjs","vscode","environmental variables"],"articleSection":["Tech Insider","Code Hacks"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/imagga.com\/blog\/autotagging-uploads-with-nodejs\/#respond"]}]},{"@type":"Person","@id":"https:\/\/imagga.com\/blog\/#\/schema\/person\/387e81bf6c4ad0798a7d889e6eac4aa2","name":"Alex Vantson","url":"https:\/\/imagga.com\/blog\/author\/mrvdot\/"}]}},"_links":{"self":[{"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/posts\/1874"}],"collection":[{"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/comments?post=1874"}],"version-history":[{"count":32,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/posts\/1874\/revisions"}],"predecessor-version":[{"id":3235,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/posts\/1874\/revisions\/3235"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/media\/1873"}],"wp:attachment":[{"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/media?parent=1874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/categories?post=1874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imagga.com\/blog\/wp-json\/wp\/v2\/tags?post=1874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}