Categories
discuss

Setting variables by name in Java

I’m looking to implement something in Java along the lines of:

class Foo{
 private int lorem; //
 private int ipsum;      

 public setAttribute(String attr, int val){
  //sets attribute based on name
 }

 public static void main(String [] args){
  Foo f = new Foo();
  f.setAttribute("lorem",1);
  f.setAttribute("ipsum",2);
 }

 public Foo(){}
}

…where a variable is set based on the variable name without the variable names hard-coded and without using any other data structures. Is this possible?

Answer

Here’s how you might implement setAttribute using reflection (I’ve renamed the function; there are different reflection functions for different field types):

public void setIntField(String fieldName, int value)
        throws NoSuchFieldException, IllegalAccessException {
    Field field = getClass().getDeclaredField(fieldName);
    field.setInt(this, value);
}
Categories
discuss

Select multiple descendants with jQuery?

I have this form:

<form name="customize">
    Only show results within 
        <select name="distance" id="slct_distance">
            <option>25</option>
            <option>50</option>
            <option>100</option>
            <option value="10000" selected="selected">Any</option>
    </select> miles of zip code
    <input type="text" class="text" name="zip_code" id="txt_zip_code" />
    <span id="customize_validation_msg"></span>
</form>

How can I select the input and select with one jQuery selector?

I tried this but it selected all of the selects and inputs on the page:

$("form[name='customize'] select,input")

Answer

The comma in the selector string separates completely separate expressions, just like in CSS, so the selector you’ve given gets the select elements within the form named “customize” and all inputs on the form (as you’ve described). It sounds like you want something like this:

$("form[name='customize'] select, form[name='customize'] input")

or if you’re not into repitition, this:

$("form[name='customize']").children("select, input")
Categories
discuss

Preventing AJAX memory leaks

I am working on a web application that is designed to display a bunch of data that is updated periodically with AJAX. The general usage scenario would be that a user would leave it open all day and take a glance at it now and then.

I am encountering a problem where the browsers memory footprint is growing slowly over time. This is happening in both Firefox and IE 7 (Although not in Chrome). After a few hours, it can cause IE7 to have a footprint of ~200MB and FF3 to have a footprint of ~400MB.

After a lot of testing, I have found that the memory leak only occurs if the AJAX calls are being responded to. If the server doesn’t respond to anything, I can leave the page open for hours and the footprint won’t grow.

I am using prototype for my AJAX calls. So, I’m guessing there is an issue with the onSuccess callback creating these memory leaks.

Does anyone have any tips on preventing memory leaks with prototype / AJAX? Or any methods on how to troubleshoot this problem?

EDIT: found out the issue lies in a js graphing library I am using. Can be seen here.

Answer

The biggest thing you can watch out for is events, and how you assign them.

For instance, take this scenario (since you haven’t provided one):

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl, {
            onSuccess: function() {
                $$('#ajaxResponseTarget .someButtonClass').invoke('observe', 'click', function() {
                    ...
                });
            }
        });
    });
</script>

This will create a memory leak, because when #ajaxResponseTarget is updated (internally, Prototype will use innerHTML) elements with click events will be removed from the document without their events being removed. The second time you click someButton, you will then have twice as many event handlers, and garbage collection can’t remove the first set.

A way to avoid this is to use event delegation:

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $('ajaxResponseTarget').observe('click', function(e) {
        if(e.element().match('.someButtonClass')) {
            ...
        }
    });
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl);
    });
</script>

Because of the way DOM events work, the “click” on .someButtonClass will fire also on #ajaxResponseTarget, and Prototype makes it dead simple to determine what element was the target of the event. No events are assigned to elements within #ajaxResponseTarget, so there is no way for replacing its contents to orphan events from targets within.

Categories
discuss

Javascript callback functions and recursion

This is kind of a brainteaser question, since the code works perfectly fine as-is, it just irritates my aesthetic sense ever so slightly. I’m turning to Stack Overflow because my own brain is failing me right now.

Here’s a snippet of code that looks up an address using the Google Maps JS API and places a marker on a map. However, sometimes the initial lookup fails, so I want to repeat the process with a different address.

geocoder.getLatLng(item.mapstring, function(point) {
    if (!point) {
        geocoder.getLatLng(item.backup_mapstring, function(point) {
            if (!point) return;
            map.setCenter(point, 13);
            map.setZoom(7);
            map.addOverlay(new GMarker(point));
        })
        return;
    }
    map.setCenter(point, 13);
    map.setZoom(7);
    map.addOverlay(new GMarker(point));
})

(The second parameter to getLatLng is a callback function.)

Of course you can see that the three lines that center and zoom the map and add the marker are duplicated, once in the primary callback and once in the “fallback callback” (ha ha). Can you find a way to express the whole thing without any redundancy? You earn bonus points, and my adulation, if your solution works for an arbitrary number of backup map strings.

Answer

The other answers are good, but here’s one more option. This allows you to keep the same form you started with but uses the trick of naming your lambda function so that you can refer to it recursively:

mapstrings = ['mapstring1', 'mapstring2', 'mapstring3'];

geocoder.getLatLng(mapstrings.shift(), function lambda(point) {
   if(point) {
        // success
        map.setCenter(point, 13);
        map.setZoom(7);
        map.addOverlay(new GMarker(point));
    }
    else if(mapstrings.length > 0) {
        // Previous mapstring failed... try next mapstring
        geocoder.getLatLng(mapstrings.shift(), lambda);
    }
    else {
        // Take special action if no mapstring succeeds?
    }
})

The first time the symbol “lambda” is used, it is to introduce it as a new function literal name. The second time it is used, it is a recursive reference.

function literal naming works in Chrome, and I assume it works in most modern browsers, but I haven’t tested it and I don’t know about older browsers.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..