0

First - I have read ALL of the other threads on SO with the same error. NONE of them helped me one bit.

Flow:

  1. On new Customer page, fill out fields, click save
  2. Fire off method in customer_controller to create
  3. Render json with info back to the page:

    format.json {render :json => res.to_a }

  4. Page gets the array :

    Array[2] new:851

It's a properly-formatted array.

Error:

Uncaught TypeError: Cannot read property 'top' of undefined 

Trace the source:

$.ajax({
    type : "POST",
    url : "/customers",
    data : dataString,
    dataType : "json",
    success : function(data) {
      console.log(data);
      // data = data[0];
      // console.log(data);
      if (data[0] == 'error' || data[0] == 'i') {
        $("#flash_message").addClass("alert-error");
        $("#flash_message").html("<p>" + data[1] + "</p>");
        $('html,body').animate({
          scrollTop : $("#flash_message").offset().top
        }, 'slow');
      } else {
        $("#flash_message").addClass("alert-success");
        $("#flash_message").html("<p>" + data[0] + "</p>");
        $('html,body').animate({
          scrollTop : $("#flash_message").offset().top

flash_message eh? Let's see in the view:

<% flash.each do |key, value| %>
<div id="flash_message" class="alert alert-<%= key %>">
    <%= value %>

Yup, definitely a flash_message id in there.

However, we are using layouts - so there must be a timing issue. The AJAX code is in admin.html.erb layout, and we're completing our NEW customer action from the customer.html.erb view. Customer Controller has:

  layout 'admin', :except => [:show]

"show" is not our method in question here - we're using "create"

Processing by CustomersController#create as JSON

So why in the blue-bloody-blazes do we not know what "flash_message" is ?

Amir
  • 1,882
  • 17
  • 22
notaceo
  • 1,093
  • 10
  • 28

2 Answers2

1

I have encountered timing issue when trying to get sizes or positions from a web page. In most cases the problem was indeed that the object had not finished loading and therefore the data was not yet known.

As Cherniv mentioned, I also think that you may need to use the load event, as the ready event is fired before the page (and therefore also the needed layout) has finished loading. The load event is not fired until the entire page has finished so your data should then be availble.

Here's another explanation from stack overflow: load-ready events

Community
  • 1
  • 1
Jon Cole
  • 51
  • 4
0

Ok update on this - despite this block of code:

<% flash.each do |key, value| %>
<div id="flash_message" class="alert alert-<%= key %>">
    <%= value %>
<%end%>

The kicker here was me being stupid - we're not even using FLASH in Rails for these messages!!!

We're returning a JSON object to the browser via an AJAX call which was made to a method inside a the customer's controller (whew - that was a mouthful).

So my JSON cannot find "flash_message" because it doesn't exist unless I am calling the flash method in Rails

I had to create yet another div for a "standard" type of message. Now I'm not sure why my team developed two ways to print messages back to the window, but that's a different topic...

<% flash.each do |key, value| %>
<div id="flash_message" class="alert alert-<%= key %>">
    <%= value %>
<%end%>
<div id="flash_message" class="alert" style="display:none" />

We give it a display:none style because the "alert" class leaves this ugly yellow bar across the entire page (bootstrap goodness!)

So the answer was that I was never invoking flash.each, and the div only exists when you invoke flash.each - it was printed and tricking my eyes but not really present.

Pro-tip: always click "view source" on the actual page you've rendered instead of just staring at your code for days on end.

notaceo
  • 1,093
  • 10
  • 28