sunng87 / handlebars-iron

Handlebars middleware for Iron web framework
MIT License
119 stars 20 forks source link

Passing array with object as first element as object array as second is broken. #17

Closed nicklan closed 8 years ago

nicklan commented 8 years ago

Shown by the following example:

Add the following two files to the examples and examples/templates as array.rs and array.hbs respectively:

extern crate iron;
extern crate env_logger;
extern crate handlebars_iron as hbs;
extern crate rustc_serialize;

use iron::prelude::*;
use iron::{status};
use hbs::{Template, HandlebarsEngine};
use rustc_serialize::json::{ToJson, Json};
use std::collections::BTreeMap;

struct Team {
    name: String,
    pts: u16
}

impl ToJson for Team {
    fn to_json(&self) -> Json {
        let mut m: BTreeMap<String, Json> = BTreeMap::new();
        m.insert("name".to_string(), self.name.to_json());
        m.insert("pts".to_string(), self.pts.to_json());
        m.to_json()
    }
}

fn make_data () -> Json {
    let sub_teams = vec![ Team { name: "Jiangsu Sainty".to_string(),
                             pts: 43u16 },
                      Team { name: "Beijing Guoan".to_string(),
                             pts: 27u16 },
                      Team { name: "Guangzhou Evergrand".to_string(),
                             pts: 22u16 },
                      Team { name: "Shandong Luneng".to_string(),
                             pts: 12u16 } ];

    let team = (Team { name: "Main Team".to_string(),
                       pts: 123u16 },
                sub_teams);
    team.to_json()
}

/// the handler
fn hello_world(_: &mut Request) -> IronResult<Response> {
    let mut resp = Response::new();

    let data = make_data();
    resp.set_mut(Template::new("array", data)).set_mut(status::Ok);
    Ok(resp)
}

fn main() {
    env_logger::init().unwrap();

    let mut chain = Chain::new(hello_world);
    chain.link_after(HandlebarsEngine::new("./examples/templates/", ".hbs"));
    println!("Server running at http://localhost:3000/");
    Iron::new(chain).http("localhost:3000").unwrap();
}
<html>
  <head>
    <title>Array Test</title>
  </head>
  <body>
    Main: <b>{{[0].name}}</b>: {{[0].pts}}
    <ul>
    {{#each this.[1]}}
      <li class="{{#if @first}}champion{{/if}}">
      {{@index}}. <b>{{name}}</b>: {{pts}} -- {{this}}
      </li>
    {{/each}}
    </ul>
    {{this.[1]}} <- output correct json
  </body>
</html>

The output will have all nulls for the sub-teams, even though it will print four lines with all null, so it is iterating over the right thing. More simple tests of array iteration seem to work, so I suspect something about the complexity of the json being passed is breaking things.

Accessing the sub-team array as just [1] also doesn't work.

sunng87 commented 8 years ago

Thanks for reporting. This seems to be an issue with the each helper. I will look into it.

sunng87 commented 8 years ago

This should be fixed in handlebars 0.11.2. Please run cargo update and test again. Thanks!

nicklan commented 8 years ago

yep, seems to work. thanks for the super fast response!