How to Setup Image URLs on Your Rails API & Render them on your JavaScript Front-End in 10 Steps
By: Koray Ozkal
Tags: Rails, Ruby on Rails, Javascript Tips, JavaScript

Would you like to add images to your small web app, googled & searched Stack Overflow in agony, got lost in gem hunting, and confused by all the information? This article is for you!

In coding schools, building small web apps is an essential part of the curriculum. In most cases, you end up building an app, listing your favorite books, DVDs, albums, movies, basketball/hockey/baseball cards, comicbooks, or something similar in nature. After looking into my classmates’ demos, noticing all the pretty images in their apps, I thought it would be great to display all the amazing cover art for my Comicbook App! Should be easy right? Not quite so.

In my case, searching and reading all Stack Overflow posts, questions, and comments turned into an agonizing process. First of all, there were many different ways to accomplish setting up, storing, rendering, and uploading an image in your app. There are so many fancy gems that could help you. However, if you are racing against time to deliver a school project, sometimes it really helps to keep it simple and go back to basics. Therefore, I decided to follow a very simple method: adding an image URL represented as a string and transmit it using JSON. I will use Rails as an API for creating my back-end and JavaScript for my front-end. (If you are interested in a step by step guide in building a rails API, please also check my The Startup article https://medium.com/swlh/beginners-guide-to-building-a-rails-api-7b22aa7ec2fb)

STEP 1 — Add the IMAGE URL as a STRING when generating models

rails g model Comicbook title image_url publisher_id:integer number:integer artist writer --no-testframework

Quick note rails will default to a string if we don’t specify a type for our attributes. Also, don’t forget to run rails db:create && rails db:migrate to complete creating your database and migration.

STEP 2 — Add the IMAGE URL to your SEED data

Now let’s go to our seeds file db/seeds.rb and make sure we have the image_url included while creating a new comicbook in our seed data.

Comicbook.create(title: “Flash Rebirth”, image_url: “https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/48457/DIG010147_1._SX360_QL80_TTD_.jpg", artist: “Ethan Van Sciver”, writer: “Geoff Johns” , publisher_id: dc.id)

STEP 3— Render JSON from a Rails controller

A JSON string contains either an array of values or an object (an associative array of name/value pairs). By using render json: in our Rails controller, we take the entire Comicbook model, have Rails convert them to a JSON string( JavaScript Object Notation), and send them out on request. This is useful for AJAX calls in JavaScript where you want to return JavaScript objects. I am copying index controller action as an example.

class ComicbooksController < ApplicationController def index comicbooks= Comicbook.all

render json: comicbooks #if you are using a serializer

#render json: ComicbookSerializer.new(comicbooks) end

*Don’t forget to also add a create action if you are letting your end-user to submit a form. Make sure image_url is listed in your STRONG PARAMS, in your controller if you are letting end-user submit information and create a new instance of comicbook with a mass assignment of params.

class ComicbooksController < ApplicationController #YOUR ACTIONS HERE FIRST private def comicbook_params

params.require(:comicbook).permit(:title, :writer, :artist,

:image_url, :publisher_id,)

end

STEP 4 — *Only if you are using Serializers — Don’t forget to add image_url as an attribute in your Serializer Class.

class ComicbookSerializer include FastJsonapi::ObjectSerializer

attributes :title, :writer, :artist, :image_url, :publisher_id,

:publisher end

STEP 5 — Test your data.

Now, if we set everything else right with our application, visiting or fetching http://localhost:3000/comicbooks will now produce our array of comicbook objects and each object will have an image_url!!!



"id": "2",

"type": "comicbook",

"attributes": {

"title": "Flash Reborn",

"writer": "Geoff Johns",

"artist": "Ethan Van Sciver",

"image_url": "https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/48457/DIG010147_1._SX360_QL80_TTD_.jpg",

"publisher_id": 2,

"publisher": {

"id": 2,

"name": "DC Comics",

"created_at": "2020-10-25T07:05:29.840Z",

"updated_at": "2020-10-25T07:05:29.840Z"

}

}

} "id": "2","type": "comicbook","attributes": {"title": "Flash Reborn","writer": "Geoff Johns","artist": "Ethan Van Sciver","publisher_id": 2,"publisher": {"id": 2,"name": "DC Comics","created_at": "2020-10-25T07:05:29.840Z","updated_at": "2020-10-25T07:05:29.840Z"

NOW everything is set on our back-end app and we can fetch the image URLs on our Javascript front-end! We will create the folders and files below:

1- comicbook_frontend/index.hmtl

2- comicbook_frontend/src/index.js

3- comicbook_frontend/src/comicbook.js

STEP 6 — Set up your index.html and connect with your JS files

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Comicbook Geek App</title> <!-- JS Connection Tags --> <script src="src/index.js" charset="utf-8"></script> <script type="text/javascript" src="src/comicbook.js"></script> <script type="text/javascript" src="src/index.js"></script> </head> <body> <h1>COMICBOOK APP</h1> <br><br> <h2>MY COMICBOOKS</h2> <div id="comicbooks-container"> </div> </body> </html>

STEP 7 — Setup your endpoint in your index.js

const endPoint = "http://localhost:3000/comicbooks"

Make sure it is in your global scope!

STEP 7— Create your Comicbook class and constructor and add your image_url attribute

class Comicbook { constructor(comicbook, comicbookAttributes) { this.id = comicbook.id; //IMPORTANT:Don't forget to list all the other attributes here!!! this.image_url = comicbookAttributes.image_url; Comicbook.all.push(this);

// pushing each new instance of Comicbook object to an array }

STEP 8 — Now we are creating a renderComicbook() function

renderComicbook() { return ` <div data-id=${this.id}> <img src=${this.image_url} height=”300" width=”200"> <p>${this.title}</p> //IMPORTANT!: Don't forget to list all the other attributes!!! </div> <br><br>`; } } Comicbook.all = []; //where we are pushing each new instance

STEP 9— Create a function for fetching comicbooks for index action, iterate a new comicbook instance with forEach, and render .

function getComics() { fetch(endPoint) .then(response => response.json()) .then(comics => { comics.data.forEach(comicbook => { let newComicbook = newComicbook(comicbook,comicbook.attributes) document.querySelector(‘#comicbooks-container’).innerHTML += newComicbook.renderComicbook() }) }) }

STEP 10— Open your index.hmtl and test!

Yes!!! We did it!!

Happy coding and please let me know if you have any comments or suggestions!

Resources:

https://medium.com/swlh/beginners-guide-to-building-a-rails-api-7b22aa7ec2fb)