Since someone else already offered a solution, I’m going to be a bit
critical.
Sorry about that, but your question alone suggests you really need to
learn a
lot more about how Ruby (or Rails) and JavaScript communicate.
I apologize in advance – you said you’re a newbie – but this might be
harsh.
I want you to understand why this is wrong, and why it’s so fractally
wrong,
before you try to do it right.
On Saturday, May 15, 2010 07:45:09 pm Brandon Jake12jake wrote:
So I’m very new to both ruby and javascript, but the basic problem is. I
have a ruby array @events_this_month, and i’m running a javascript loop
that basically needs the information from this array.
So, think about what’s actually going on.
You’re probably using Rails. Ruby is not Rails, and this is not a Rails
mailing list. Even if you’re using another Ruby framework, though, it
looks
very much like you are running Ruby on the server side, and JavaScript
in a
web browser.
That means you’ve got two programs which are not only not in the same
language, they aren’t even on the same machine!
So no, you can’t just access the array. First you need to get the data
from
your Ruby script to your JavaScript program, somewhere over the network.
Then
you can worry about how to loop over it.
The problem is I
can’t seem to set the proper index for my ruby array. What I have looks
like this:
for( var i = 0; i < 3; i++)
{
var title = ‘<%= @events_this_month[i].title %>’;
alert(title);
}
First of all, how do you know it’s always 3? And why on earth wouldn’t
you go
off the length of the array?
But again, try to think about what’s happening here. You’ve shown me
what
looks like a Ruby template. What does a template actually do?
Ruby is going to run through that, and this is the important point,
BEFORE it
gets sent to the client. That means, before your javascript is executed
at
all, Ruby will have finished with that page. That means, Ruby just sees:
a big blob of text
@events_this_month[i].title
another big blob of text
The variable ‘i’ doesn’t exist at this point. Not in Ruby, because it’d
be a
JavaScript variable. Not in JavaScript, because the JavaScript program
isn’t
running yet.
Just because two languages are present in the same source file doesn’t
mean
they can be mashed together like that.
One more thing: You already have a vulnerability in that. What if
someone puts
an apostrophe in the title?
I’ve also tried:
<%= $j = 0 %>
Globals are evil. Never use them. You’re very carefully using ‘var’ in
JavaScript – why would you use a global variable in Ruby, especially
for an
iterator variable!
for( var i = 0; i < 3; i++)
{
var title = ‘<%= @events_this_month[$j].title %>’;
I can’t imagine why you’d expect this to work, either. JavaScript is
incrementing a variable called i, and Ruby is using a variable called
$j. How
is either language supposed to know they’re related?
alert('<%= $j %>');
<%= $j = $j +1 %>
}
So remember, the for loop is JavaScript. Ruby just sees it as a bunch of
text.
That means Ruby sees this:
TEXT
$j = 0
TEXT
@events_this_month[$j].title
TEXT
$j
TEXT
$j = $j +1
TEXT
Or, if you take out the text, here’s what Ruby sees:
$j = 0
@events_this_month[$j].title
$j
$j = $j +1
Any suggestions on how I can access the correct index in my ruby array
during the javascript loop?
Nope, that’s completely impossible, because you can’t access Ruby during
the
JavaScript loop.
Now, the suggested solution will work, but I want you to think about how
and
why it works:
var events = <%= @events_this_month.to_json %>;
for (var i=0; i<events.length; i++)
alert(events[i].title);
That will convert the entire Ruby array to JavaScript, which means Ruby
sees
this:
TEXT
@events_this_month.to_json # hey, something I can do!
TEXT
JavaScript will see something like this:
var events = [
{ title: ‘First event’, time: ‘Monday’ },
{ title: ‘Second event’, time: ‘Tuseday’ },
{ title: ‘Third event’, time: ‘Wednesday’ }
];
for (var i=0; i < events.length; i++)
alert(events[i].title);
Now, if you really only need the title of the event, you could simplify
it a
bit (and save some bandwidth) by only sending that:
var titles = <%= @events_this_month.map(&:title).to_json %>;
for (var i=0; i<titles.length; i++)
alert(titles[i]);
Think about why that’s the case. What will Ruby see? What will
JavaScript see?
One more thing: It was painfully obvious this time what your mistake
was, but
in the future, you may want to tell us a little more. “I’m using Rails”
would
be a good start, but the most important thing is, if you ever catch
yourself
writing “It doesn’t work,” STOP! And tell us what actually happened.
“It doesn’t work” is useless. It’s like going to the doctor and saying
“I feel
sick.” What are your symptoms? What happens, and what did you expect to
happen? What error messages did you get? There’s all kinds of things you
can
say other than “It doesn’t work.”