eonu
eonu

Reputation: 71

Ruby On Rails - Rendering a partial after page load

I'm working on an application that makes some calls to the Twitter and Spotify APIs. After the user is authenticated with twitter, they are redirected to playlist.erb which is the callback url.

My problem is that the playlist.erb page takes a while to render because first we must make a call to fetch all tweets found on the users Twitter page, then try to find information about songs/artists, then use the Spotify API to search for a song that is closest to what information the user specified. Doing this for each tweet takes quite a while. For 10 tweets it sometimes takes between 5-10 seconds. The limit is 50 tweets in total.

The current playlist.erb page after it is fully loaded looks like this.

My question is, is there a way that I can render the page first, then get the partials for each individial tweet to render one at a time, adding a new row for each tweet as it loads?

I've read that I should use something called AJAX, but I'm not sure how exactly to implement that here.

Also I'm aware that my view could use fixing in terms of CSS refactoring and not using the deprecated <center></center> HTML tags. And I should probably do a whole refactor of the system using proper MVC.


In the playlist.erb, a call to the Twitter API is made through the TweetsController to find all tweets from a page. the _tweet.erb partial is then rendered to this view for each tweet when new_tweet(tweet.text) is called. This method makes a call to the Spotify API to find details about the song mentioned in the tweet.

new_tweet is a method in a helper called playlist_helper.rb.

load_tweets is a method in a controller called tweets_controller.rb.

I realise that this is quite a bit of logic to put in a view, which is why the page takes quite long to load I guess.

playlist.erb

<% loaded_tweets = TweetsController.load_tweets(current_user) %>
<% if loaded_tweets.any? %>
  <table class='tweet_view'>
    <thead>
      <tr class='tweet_row'>
        <th class="fixed_cover"><div class='tableheader'><h6 style='color:white'>Cover</h6></div></th>
        <th class="fixed_spotify"><div class='tableheader'><h6 style='color:white'>Spotify</h6></div></th>
        <th class="fixed_title"><div class='tableheader'><h6 style='color:white'>Track title</h6></div></th>
        <th class="fixed_artist"><div class='tableheader'><h6 style='color:white'>Artist</h6></div></th>
        <th class="fluid"><div class='tableheader'><h6 style='color:white'>Album</h6></div></th>
      </tr>
    </thead>
    <tbody>
      <% loaded_tweets.reverse_each.each do |tweet| %>
        <%=new_tweet(tweet.text)%>
      <% end %>
    </tbody>
  </table>
<% else %>
    <center>
      <p><h8><b>No tweets found!</b></h8></p>
    </center>
<% end %>

The _tweet.erb partial just adds a new row for each song.

_tweet.erb

<tr class='tweet_row'>
  <td class='tweet_column'>
    <div class='tablerow#cover'>
      <%= image_tag(@cover,:class => 'album_cover')%>
    </div>
  </td>
  <td class='tweet_column'>
    <div class='tablerow#spotify'>
      <h5><%= link_to image_tag('spotify', :class => 'spotify_image'), 'https://open.spotify.com/track/'+@spotify %></h5>
    </div>
  </td>
  <td class='tweet_column'>
    <div class='tablerow'>
      <h5><%=@track_name%></h5>
    </div>
  </td>
  <td class='tweet_column'>
    <div class='tablerow'>
      <h5><%=@artist%></h5>
    </div>
  </td>
  <td class='tweet_column'>
    <div class='tablerow'>
      <h5><%=@album%></h5>
    </div>
  </td>
</tr>

Upvotes: 1

Views: 2116

Answers (1)

Ranganath Nyamagoudar
Ranganath Nyamagoudar

Reputation: 81

Change playlist.erb to playlist.html.erb

<div id="tweets">
    <%= render 'tweet') %>
</div>

.... ....

<script>
$( document ).ready(function() {
    // call the controller function here
});
</script>

In controller methode add

.... ....

respond_to do |format|
     format.js
  end

create one more file in views folder like action_name.js.erb and add

$('#tweets').html('<%= j(render "tweet") %>')

Upvotes: 1

Related Questions