Building a Wishlist App using Rails + jQuery

Lisa Huang
6 min readSep 9, 2018

--

Extending my Wishlist app with jQuery front end and API calls

Part I: Building a Wishlist App using Ruby on Rails

Since building my wishlist app using Ruby on Rails, I have extended my app by adding dynamic features through jQuery and a JSON API.

In this project, I’ve added three new features:

  1. Users can navigate to the next Product without refreshing the page
  2. Users can view all products associated with a chosen wishlist
  3. Users can create a new wishlist and review the new wishlist information once it is successfully created

You can see a demo video of my app here:

Walkthrough of my Wishlist app’s new features

Adding jQuery to Gemfile and asset pipeline

Starting with Rails 5.1, jQuery is not included by default. In order to use jQuery, we must first add it to the Gemfile and install it:

gem 'jquery-rails'

bundle install

Next, update the JS manifest file with jQuery paths:

//= require jquery3
//= require jquery_ujs
//= require_tree .

When we include the manifest file in our layout with javascript_include_tag, and the application layout file is a great place to include this tag:

<%= javascript_include_tag 'application' %>

The rails asset pipeline will then look for all of the files listed in the Asset Path — including jQuery and all .js files in the assets/javascript folder.

Creating a Rails API

In order to build the three features above, I needed to create a Rails backend API (Application Programming Interface) that will interact with a jQuery frontend. My rails API will provide access to the data stored in my database in JSON (JavaScript Object Notation) format, which looks a lot like a Ruby hash:

{
"id": 74,
"name": "2019 World Traveler",
"price": 26,
"url": "https://riflepaperco.com/shop/desk/calendars/2019-world-traveler/",
"category": {
"id": 11,
"name": "Calendars",
"link": "https://riflepaperco.com/shop/desk/calendars/"},
"wishlist": null
}

My app’s jQuery frontend is able to fetch /get JSON data from the API, use the JSON data in my JS code (e.g. display a product on button click), and ultimately render data to the HTML DOM without refreshing the page.

But how exactly can we create a Rails API?

Adding ActiveModel::Serializer to Gemfile and asset pipeline

ActiveModel::Serializer(AMS) provides a way of creating custom JSON by representing each resource as a class that inherits from ActiveModel::SerializerHendra Uzia

In another word, AMS provides a convention-based approach to convert our Ruby models into JSON objects, including model associations! In order to use AMS, we must first add it to our Gemfile and install it:

gem 'active_model_serializers'

bundle install

Next, generate serializers for each data model using rails generator commands:

rails g serializer product

This will create a serializer in app/serializers/product_serializer.rb with a single attribute: id:

class ProductSerializer < ActiveModel::Serializer  attributes :idend

You can add more attributes and model associations to the file, but pay attention to only include data that you want to expose/share with your end client (in this case, the jQuery frontend):

class ProductSerializer < ActiveModel::Serializer  attributes :id, :name, :price, :url, :image_link  belongs_to :category  belongs_to :wishlistend

This mirrors the Product model associations:

class Product < ActiveRecord::Base  belongs_to :wishlist  belongs_to :categoryend

Now we are ready to build our new features!

Feature 1: Navigate to the next product on product page

Product page’s “Next Product” feature

User Story: As a user, I need to be able to see the next product, so that I can decide what to buy!

In order to fulfill the user story above, we need to:

  • Attach an event listener to the “Next Product” button
  • On button click, the app should somehow get the data for the next product and update the page with this information (without refreshing the page)

How can we get data from rails API? By using AJAX (Asynchronous JavaScript And XML), of course!

AJAX use a browser built-in XMLHttpRequest object to request data from a web server and JavaScript to use the data or display data in HTML DOM — W3School

How AJAX works

Here’s the actual code snippet showing how I implemented this feature in Product show view, note that I’m using a jQuery GET $.get() request to fetch data asynchronously from the server:

Feature 2: View all products associated with a chosen wishlist

Wishlist page’s “Show products” feature

User Story: As a user, I need to be able to see all products associated with a wishlist, so that I can review my shopping list!

In order to fulfill the user story above, we need to:

  • Attach an event listener to the “Show Products” button
  • On button click, the app should get data for all products associated with the chosen wishlist, and update the page with this information (without refreshing the page)

You guessed it — we will use the handy AJAX request again! Here’s the actual code snippet showing how I implemented this feature in Wishlist show view, note that I’m using a GET request again:

Feature 3: Create a new wishlist

Create a new Wishlist feature

User Story: As a user, I need to be able to create a new wishlist and see it on screen right after, so that I can check my wishlist information is correct!

In order to fulfill the user story above, we need to:

  • Attach an event listener to the “Create Wishlist” button
  • On button click, the app should get all form input values and create a new Wishlist object. This new object should be persisted to our database.
  • If the object is created successfully, update the page with information for the new wishlist (without refreshing the page)

Here’s the actual code snippet showing how I implemented this feature in Wishlist new view, note that I’m attaching an event listener to form submission to setupCreateWishlist:

To stay organized, I’ve extracted my JS code into a separate file in assets/javascript , which the asset pipeline will use the JS manifest we configure in Rails to automatically concatenate all files listed into one JS file in production.

As you may remember from your CRUD operations, to create a new resource, you need to send a POST request. We will use the jQuery POST $.post() method to send an asynchronous request to submit the data to the server. If this is successful, we will get the response back in JSON format.

We will pass our serialized form input value (i.e. values) as argument to createWishlist(), the AJAX function that sends a HTTP POST request. If the request succeeds, we will receive response data in JSON format from our Rails API and create a new Wishlist object with Javascript class declaration: class Wishlist.

JavaScript classes, introduced in ECMAScript 2015 (ES6), are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. — MDN

The constructor method initialize an instance, it is called automatically to initialize objects and keep data encapsulated, thereby keeping the JSON data private and inaccessible to the outside world. TheWishlist class has a prototype method, updateHTML() which will render data onto the page:

Voila! And we have implemented three new features using a jQuery frontend in our app. In this project, I’ve learned about Rails asset pipeline process, building and using an API, and using AJAX calls to GET and POST data to my server!

I invite you to check out my Github repo here, clone or fork it and poke around! If you spot a bug, please file an issue and let me know. Contributions are always welcomed! And thank you for taking the time to read through this blog.

--

--

Lisa Huang

Product Lead at Planet | 2x Founder, dabbling in TypeScript | My @TEDx talk: bit.ly/LisaHuangTEDx