Categories
discuss

Sorting a JavaScript object by property name

I’ve been looking for a while and want a way to sort a Javascript object like this:

{
    method: 'artist.getInfo',
    artist: 'Green Day',
    format: 'json',
    api_key: 'fa3af76b9396d0091c9c41ebe3c63716'
}

and sort is alphabetically by name to get:

{
    api_key: 'fa3af76b9396d0091c9c41ebe3c63716',
    artist: 'Green Day',
    format: 'json',
    method: 'artist.getInfo'
}

I can’t find any code that will do this. Can anyone give me some help?

Answer

UPDATE from the comments:

This answer is outdated. In ES6 objects keys are now ordered. See this question for an up-to-date answer

By definition, the order of keys in an object is undefined, so you probably won’t be able to do that in a way that is future-proof. Instead, you should think about sorting these keys when the object is actually being displayed to the user. Whatever sort order it uses internally doesn’t really matter anyway.

By convention, most browsers will retain the order of keys in an object in the order that they were added. So, you could do this, but don’t expect it to always work:

function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}
Categories
discuss

How to map collections in Dozer

I’d like to do something like:

ArrayList<CustomObject> objects = new ArrayList<CustomObject>();
...
DozerBeanMapper MAPPER = new DozerBeanMapper();
...
ArrayList<NewObject> newObjects = MAPPER.map(objects, ...); 

Assuming:

<mapping>
  <class-a>com.me.CustomObject</class-a>
  <class-b>com.me.NewObject</class-b>   
    <field>  
      <a>id</a>  
      <b>id2</b>  
    </field>  
</mapping>

I tried :

ArrayList<NewObject> holder = new ArrayList<NewObject>();
MAPPER.map(objects, holder);

but the holder object is empty. I also played with changing the second argument without any luck…

Answer

To quote:

“Nested collections are handled automatically, but you are correct that top level collections need to be iterated over. Currently there isn’t a more elegant way to handle this.”

Someone has figured a way to do it without a looping construct in your code base, but I think it’s just easier (and more readable/maintainable) to put it in your code. Hopefully they’ll add this ability sooner than later.

Categories
discuss

Axis2’s wsdl2java fails on RPC/Encoded style web services

Is there any alternative to Axis2? Or the way to make it work (different data binding, for example)?

Retrieving document at '...'.
Exception in thread "main" org.apache.axis2.wsdl.codegen.CodeGenerationException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at org.apache.axis2.wsdl.codegen.CodeGenerationEngine.generate(CodeGenerationEngine.java:271)
        at org.apache.axis2.wsdl.WSDL2Code.main(WSDL2Code.java:35)
        at org.apache.axis2.wsdl.WSDL2Java.main(WSDL2Java.java:24)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at org.apache.axis2.wsdl.codegen.extension.SimpleDBExtension.engage(SimpleDBExtension.java:53)
        at org.apache.axis2.wsdl.codegen.CodeGenerationEngine.generate(CodeGenerationEngine.java:224)
        ... 2 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.axis2.wsdl.codegen.extension.SimpleDBExtension.engage(SimpleDBExtension.java:50)
        ... 3 more
Caused by: org.apache.axis2.schema.SchemaCompilationException: can not find type {http://schemas.xmlsoap.org/soap/encoding/}Array from the parent schema ...        at org.apache.axis2.schema.SchemaCompiler.copyMetaInfoHierarchy(SchemaCompiler.java:1296)
        at org.apache.axis2.schema.SchemaCompiler.processComplexContent(SchemaCompiler.java:1258)
        at org.apache.axis2.schema.SchemaCompiler.processContentModel(SchemaCompiler.java:1153)
        at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1097)
        at org.apache.axis2.schema.SchemaCompiler.processNamedComplexSchemaType(SchemaCompiler.java:1017)
        at org.apache.axis2.schema.SchemaCompiler.processSchema(SchemaCompiler.java:931)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:766)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:552)
        at org.apache.axis2.schema.SchemaCompiler.process(SchemaCompiler.java:1991)
        at org.apache.axis2.schema.SchemaCompiler.processParticle(SchemaCompiler.java:1874)
        at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1081)
        at org.apache.axis2.schema.SchemaCompiler.processNamedComplexSchemaType(SchemaCompiler.java:1017)
        at org.apache.axis2.schema.SchemaCompiler.processSchema(SchemaCompiler.java:931)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:766)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:552)
        at org.apache.axis2.schema.SchemaCompiler.process(SchemaCompiler.java:1991)
        at org.apache.axis2.schema.SchemaCompiler.processParticle(SchemaCompiler.java:1874)
        at org.apache.axis2.schema.SchemaCompiler.processComplexType(SchemaCompiler.java:1081)
        at org.apache.axis2.schema.SchemaCompiler.processAnonymousComplexSchemaType(SchemaCompiler.java:980)
        at org.apache.axis2.schema.SchemaCompiler.processSchema(SchemaCompiler.java:934)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:592)
        at org.apache.axis2.schema.SchemaCompiler.processElement(SchemaCompiler.java:563)
        at org.apache.axis2.schema.SchemaCompiler.compile(SchemaCompiler.java:370)
        at org.apache.axis2.schema.SchemaCompiler.compile(SchemaCompiler.java:280)
        at org.apache.axis2.schema.ExtensionUtility.invoke(ExtensionUtility.java:103)
        ... 8 more

NOTE: Apache CXF fails as well 🙁

Answer

There are only 3 options that I have found that can be used in Java for old-style rpc/encoded web services:

1) SUN’s reference implementation of JAX-RPC (wscompile)

2) WebLogic’s clientgen (I used 8.1 version)

3) Axis1 v1.4 wsdl2java

Originally we used Axis 1.4 for that and it showed quite poor performance on relatively large service responses (>20k) i.e. client processing time increased more than twice comparing to plain HTTP request without parsing. And the time grows if response gets bigger. It took more than 30s to just deserialize 1MB large respose.

SUN’s generated client didn’t really work and it failed on request with the message:

unexpected element name: 
   expected=getSubscriberInfoReturn, 
   actual={ws.generated.api}getSubscriberInfoReturn

I have tried using WebLogic’s 8.1 clientgen, and compared client code to Axis 1.4 generated client’s performance. And Axis won the race. So, even though Axis client is performing not that good on relatively large responses it still is the best option out there for old rpc/encoded web services :(.

Categories
discuss

event.preventDefault() vs. return false

When I want to prevent other event handlers from executing after a certain event is fired, I can use one of two techniques. I’ll use jQuery in the examples, but this applies to plain-JS as well:

1. event.preventDefault()

$('a').click(function (e) {
    // custom handling here
    e.preventDefault();
});

2. return false

$('a').click(function () {
    // custom handling here
    return false;
});

Is there any significant difference between those two methods of stopping event propagation?

For me, return false; is simpler, shorter and probably less error prone than executing a method. With the method, you have to remember about correct casing, parenthesis, etc.

Also, I have to define the first parameter in callback to be able to call the method. Perhaps, there are some reasons why I should avoid doing it like this and use preventDefault instead? What’s the better way?

Answer

return false from within a jQuery event handler is effectively the same as calling both e.preventDefault and e.stopPropagation on the passed jQuery.Event object.

e.preventDefault() will prevent the default event from occuring, e.stopPropagation() will prevent the event from bubbling up and return false will do both. Note that this behaviour differs from normal (non-jQuery) event handlers, in which, notably, return false does not stop the event from bubbling up.

Source: John Resig

Any benefit to using event.preventDefault() over “return false” to cancel out an href click?

Categories
discuss

HTML Form and Javascript Confirmation

I’m having a problem with submitting a form and Javascript confirmation. Basically, the following Javascript is called when the “submit” button is pressed.

function confirmation() {
    var answer = confirm("Are you sure you wish to edit?")
    if (answer)
    {
        window.location = "#editform2";
    }
}

However, when I hit the cancel instead of ok, the Javascript executes correctly, because I watch the address bar and it doesn’t update to #editform2. The form, however, still submits. It seems to refresh the page. Here’s the relevant parts from the form:

//Form is encoded in PHP
<form method="post">
//Form is in here
<input type="submit" value="Edit" onclick="confirmation()">

So the form doesn’t know where it’s going, it just refreshes the page, and the page happens to be the processor as well. So it’s processing even though I clicked cancel and the Javascript should keep it on the same page. Besides moving the processing to a different page, what are my solutions?

Answer

It works like this because it’s a sumbit button and the form is submitted in every case. Assign an id to the form and change the input type:

<form method="post" id="formid">
<input type="button" value="Edit" onclick="confirmation()">

and call this function on click:

function confirmation() {
    var answer = confirm("Are you sure you wish to edit?")
    if (answer)
    {
        document.getElementById("formid").submit();
    }
}
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..