Home > Back-end >  How do I optimize my code so that I don't have to call the entire array every time in views fro
How do I optimize my code so that I don't have to call the entire array every time in views fro

Time:02-25

I'm making a sports app to learn Rails. I've figured out how to call the API and display it how I want, but right now, I'm putting the full array in my view every time I want to call any key.

For instance, I want to make a page that shows the starting line-ups for teams using the JSON from the API, and right now I have it displaying, but the code within the view itself is pretty big and ugly.

My view:

<%= stylesheet_link_tag 'lineups' %>

<div id="lineupcontainter">
    <div id= "team1lineup">
    
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][0]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][0]["player"]["data"]["image_path"] %> </div> </div>
            
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][1]["player_name"] %> 
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][1]["player"]["data"]["image_path"] %> </div> </div>

        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][2]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][2]["player"]["data"]["image_path"] %> </div> </div>
            
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][3]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][3]["player"]["data"]["image_path"] %> </div> </div>
            
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][4]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][4]["player"]["data"]["image_path"] %> </div> </div>

        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][5]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][5]["player"]["data"]["image_path"] %> </div> </div>
            
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][6]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][6]["player"]["data"]["image_path"] %> </div> </div>
            
        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][7]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][7]["player"]["data"]["image_path"] %> </div> </div>

        <div id= "player1"><%= @schedule["data"][0]["lineup"]["data"][8]["player_name"] %>
            <div id= "playerphotos"> <%= image_tag @schedule["data"][0]["lineup"]["data"][8]["player"]["data"]["image_path"] %> </div> </div>
    </div>

My controller

def game1
    @response = RestClient.get "https://soccer.sportmonks.com/api/v2.0/fixtures/between/2022-02-01/2022-02-04/62?api_token=____&include=lineup.player,"
    {content_type: :json, accept: :json, "user_key": "____"}
    
    @schedule = JSON.parse(@response) 
    render JSON: @schedule
end

What can I do to create something where I don't have to call the entire array every time I want to put something in views?

CodePudding user response:

Something like this should work:

<div id="lineupcontainter">
<div id= "team1lineup">
  <% @schedule["data"][0]["lineup"]["data"].each do |cur_schedule|%>
    <div id= "player1">
      <%= cur_schedule["player_name"] %>
      <div id= "playerphotos"> 
        <%= image_tag cur_schedule.dig("player", "data", "image_path") %>
      </div> 
    </div> 
  <% end %>
</div>

Also, your controller has some redundant logic. You are parsing a JSON string and turning it into a ruby hash, then you take that hash and render it as a JSON string. You should be able to render the json directly.

CodePudding user response:

If you want to reduce the lines of code in your template, you can iterate over the instance variable in the .erb file. This bit of code should work if you put it in your erb file:

<div id="lineupcontainter">
  <div id="team1lineup">

    <!-- iterating on team 1 -->
    <%= @schedule["data"][0]["lineup"]["data"].map.with_index do |data, index| %>

      <!-- index will increase by 1 each iteration, starts at 0 -->
      <div id="player1"><%= data[index]["player_name"] %>
        <div id="playerphotos"> <%= image_tag data[index]["player"]["data"]["image_path"] %></div>
      </div>

    <% end %>
  </div>
</div>

I would recommend parsing that data in your controller before sending it to the template, something like this:

def game1
  @response = RestClient.get "https://soccer.sportmonks.com/api/v2.0/fixtures/between/2022-02-01/2022-02-04/62?api_token=____&include=lineup.player,"
  {content_type: :json, accept: :json, "user_key": "____"}

  schedule = JSON.parse(@response)
  # in the ERB, replace schedule["data"][0]["lineup"]["data"] with @lineup_data 
  @lineup_data = schedule["data"][0]["lineup"]["data"]

  render JSON: @lineup_data
end

Another note: you do not need to call render json: @schedule in your controller. That will call .to_json on the instance variable and it's unnecessary when rendering data in an ERB template. The Rails MVC design allows the template to access instance variables defined in controllers. See section 2.2.8 Rendering JSON for documentation.

def game1
  @response = RestClient.get "https://soccer.sportmonks.com/api/v2.0/fixtures/between/2022-02-01/2022-02-04/62?api_token=____&include=lineup.player,"
  {content_type: :json, accept: :json, "user_key": "____"}

  schedule = JSON.parse(@response)
  @lineup_data = schedule["data"][0]["lineup"]["data"]
end
  • Related