Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to pass function callbacks? #20

Closed
ctaggart opened this issue Sep 2, 2017 · 2 comments
Closed

How to pass function callbacks? #20

ctaggart opened this issue Sep 2, 2017 · 2 comments

Comments

@ctaggart
Copy link

ctaggart commented Sep 2, 2017

I am trying to figure out how to use function callbacks. In this example, I'm simply creating a numeric array and trying to filter for just the even numbers. Unfortunately, the returned array is always empty. Any idea how to make this work? Here is what I last tried:

extern crate chakracore as js;

use std::io::prelude::*;
use std::fs::File;
use js::Property;

fn main() {
    let runtime = js::Runtime::new().unwrap();
    let context = js::Context::new(&runtime).unwrap();
    let guard = context.make_current().unwrap();


    // create a JavaScript Array
    let length = 10;
    let array = js::value::Array::new(&guard, length);
    for i in 0..length {
        array.set_index(&guard, i, &js::value::Number::new(&guard, i as i32));
    }
    println!("array: {:?}", array.len(&guard));


    // try filtering it
    let is_even = js::value::Function::new(&guard, Box::new(|guard, info| {
        //        let i = info.arguments[0].to_integer(guard);
        //        println!("i: {:?}", i);
        //        Ok(js::value::Boolean::new(guard, i % 2 == 0).into())
        println!("is_even");
        Ok(js::value::Boolean::new(guard, true).into())
    }));

    let fn_filter = array.get(&guard, &Property::new(&guard, "filter")).into_function().unwrap();

    let filtered_array = fn_filter.call(&guard, &[&is_even]).unwrap(); //.into_array().unwrap();
    println!("filtered_array: {:?}", filtered_array);

    //    for v in filtered_array.iter(&guard){
    //        println!("filtered v: {:?}", v);
    //    }

}
@ctaggart ctaggart changed the title How to filter a JavaScript array? How to pass function callbacks? Sep 2, 2017
@darfink
Copy link
Owner

darfink commented Sep 3, 2017

You are calling the filter method without any context (i.e this is not set to an instance).
Which roughly corresponds to this javascript:

let array = [];
for (var i = 0; i < 10; i++) {
  array.push(i);
}
let is_even = (x) => x % 2 == 0;
let fn_filter = array.filter;
fn_filter(is_even);

Therefore your solution is to call fn_filter with the array instance:

let filtered_array = fn_filter.call(&guard, &[&is_even]).unwrap();
// --->
let filtered_array = fn_filter.call_with_this(&guard, &array, &[&is_even]).unwrap();

@ctaggart
Copy link
Author

ctaggart commented Sep 3, 2017

Thank you for the clear explanation. It works great.

Cleaned up & works:

extern crate chakracore as js;

use js::Property;

fn main() {
    let runtime = js::Runtime::new().unwrap();
    let context = js::Context::new(&runtime).unwrap();
    let guard = context.make_current().unwrap();

    // create a JavaScript Array
    let length = 10;
    let array = js::value::Array::new(&guard, length);
    for i in 0..length {
        array.set_index(&guard, i, &js::value::Number::new(&guard, i as i32));
    }

    // try filtering it
    let is_even = js::value::Function::new(&guard, Box::new(|guard, info| {
        let i = info.arguments[0].to_integer(guard);
        Ok(js::value::Boolean::new(guard, i % 2 == 0).into())
    }));

    let fn_filter = array.get(&guard, &Property::new(&guard, "filter")).into_function().unwrap();

    let filtered_array = fn_filter.call_with_this(&guard, &array, &[&is_even]);
    println!("filtered_array: {:?}", filtered_array);
}

prints as expected:

filtered_array: Ok(Value(Array: 0,2,4,6,8))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants