I'm trying to send an IQ stanza to request the user's roster using the strophe library. Strophe provides a function for this, called sendIQ.
I tried to send the IQ stanza like this:
let iq_str = "<iq type='get' id='roster1'><query xmlns='jabber:iq:roster'/></iq>";
let parser = new DOMParser();
let iq = parser.parseFromString(iq_str, "text/xml");
XMPP.conn.sendIQ(iq, onRoster);
However, strophe's sendIQ function crashes in the var id = elem.getAttribute('id');
line with a TypeError: e.getAttribute is not a function
error, because (if I understand correctly), iq
is not a XML element object, but a XML document object.
After some searching, I was able to avoid the crash by doing this instead:
let iq_str = "<iq type='get' id='roster1'><query xmlns='jabber:iq:roster'/></iq>";
let parser = new DOMParser();
let iq = parser.parseFromString(iq_str, "text/xml").getElementsByTagName("iq")[0];
XMPP.conn.sendIQ(iq, onRoster);
But this way I'm obviously not receiving any reply since I'm not specifying the query in the passed iq
variable.
I have the feeling that I must be missing something very trivial but I've been stuck for a while. All the example I've found use jQuery, but I believe there has to be a solution without using it.
You're supposed to use Strophe's own Strophe.Builder constructor to create XML stanzas NOT the browser's DOMParser API.
Instead of invoking Strophe.Builder directly, you can do this by using the utility functions Strophe.$msg (for "message" stanzas), Strophe.$pres (for "presence" stanzas) and Strophe.$iq (for "IQ" stanzas).
Child elements are added via the c method and text via the t method.
For example:
$msg({'to': 'someond@example.org'}).c('body').t('Hello world!);
These functions and methods return the generated Strophe.Builder object. So if you have used c
to add a child, it will return that child. If you want to add another child, to the parent, you use up to move the context back up to the parent.
For example:
$msg({'to': 'someond@example.org'}).c('child1').up().c('child2');
There's also a more general, lower-level $build function which is called by $msg, $pres and $iq and which you can use to generate other XML stanzas, but it's very rarely needed.
So to create and send your specific IQ stanza, you'd do something like this:
let iq = $iq({'type':'get', 'id':'roster1'}).c('query', {'xmlns':'jabber:iq:roster'});
XMPP.conn.sendIQ(iq, onRoster);