Got a Problem? Fetch a Solution Today!

Chindalath Traymany
4 min readNov 1, 2020

--

Photo by Tim Gouw on Unsplash

What does the photo above tell you? If it screams “Well, that guy has a problem,” then it’s probably because he does! We all have our problems…but what can we do about them?

Look no further, because I have built the perfect app for us all, called Problem Solver. Running on Rails with JavaScript, this single-page-application allows you to submit your problem(s), or pitch in your solution for other problems!

Looks like a pretty simple app, right? Unfortunately for me, creating it did not feel as simple. This was my very first JavaScript app, and I’ve learned some nifty things. The first being JavaScript is a synchronous language, meaning it can only execute one thing at a time, in that order. This could be a problem if you’re trying to load a large file. Chances are, users are not going to want to wait for that file to load, and they’ll lose interest in your application.

The solution to this problem? The event loop! The event loop mimics an asynchronous process in our browser while we’re waiting for that big ol file to finish. Now, when giganto-file finishes loading, the rest of the app will be ready.

There are several ways to process requests asynchronously, including callback functions like addEventListener and setInterval, but for the sake of having a clever blog title, let’s dive into using fetch. According to MDN:

The fetch() method of the WindowOrWorkerGlobalScope mixin starts the process of fetching a resource from the network, returning a promise which is fulfilled once the response is available.

Sounds good. How can we get started? The syntax for the fetch method is as follows:

const fetchResponsePromise = fetch(resource [, init])

fetch() is a window method, but if it’s not called on window, it will automatically assume it was. It accepts two arguments: the first is the URL you would like to fetch from, and the second is an optional argument that holds additional data about the request. Below, I’ve defined the variable obj.

const obj = {    method: "POST",    headers: {        "Content-Type": "application/json",        "Accept": "application/json"    },    body: JSON.stringify({
solution: {content: content, problem_id: problemId}
})
}

Inside, you see three keys:

  1. method — here, I specify that I would like to create a new object with POST.
  2. headers — here, I’m setting the content type to “application/json,” telling the API what format to expect. I also specify which format I would like to accept the information returned, which is also “application/json.”
  3. body — this is the information that I want to include in my POST request, aka the new solution that the user is creating.

This object will be used as the second argument for my fetch request.

fetch("http://localhost:3000/solutions", obj)    .then(resp => resp.json())    .then(jsObj => {
...
})

The first argument for the request is the API I am posting to. In this case, it is my Solutions API. Then, I chain on a then to convert the response body into JSON. Taking that JSON object, I chain on another then. The second then is where I can specify what to do with the information. Inside the second then block, I render that specific problem’s solutions.

const newSolution = new Solution(jsObj.data)const foundProb = Problem.all.find(prob => {
parseInt(prob.id) === newSolution.problemId
})
foundProb.solutions.push(newSolution)const showSolution = document.createElement("li")showSolution.id = newSolution.idshowSolution.innerHTML = newSolution.contentdocument.getElementById("solutionsUl").appendChild(showSolution)

Following along with the code above, I’m taking the parsed response and assigning it to a const newSolution for easy access. Then I write a find function to assign foundProb to a problem whose ID matches the ID of the problem the newSolution belongs to. Once I find the foundProb, I add, or push, the newSolution to the collection of the foundProb's solutions.

Next, I create a new list element, showSolution. I assign this variable the proper ID and set the inner HTML to the content of newSolution. This is what we will be displaying to the user. Once the element is created and assigned the proper attributes, the last step is to append it to the DOM so that it can be viewed!

Once I add more to my application and problems/solutions grow, they’ll be able to load asynchronously with fetch. Wanna test it out? Go fetch your solution today!

Photo by K. Mitch Hodge on Unsplash

Back up. We all know a huge portion of programming is debugging. So what could we do if our fetch request gets rejected? We could catch the error.

fetch("http://localhost:3000/solutions", obj)
.then(resp => resp.json())
.then(jsObj => {
...
})
.catch(error => {
alert("Please enter a solution.")
})

In my catch, I’m assuming the error is being given because a user has submitted an empty form. If there are any errors present, it will be passed into catch as an argument. I could thenconsole.error(error) or I could add a custom message for the user, alerting them to enter a solution.

--

--

Chindalath Traymany
Chindalath Traymany

Written by Chindalath Traymany

Laotian-American woman pursuing my passion for mentally stimulating and complex problem-solving through programming.

No responses yet