[d2 lib] - API call failing with "Server connection failed for API request"

Hi,

I’m using d2 to fetch some data inside a DHIS2 app. Everything looks to be working well, until I have a query using event analytics.

As the d2 lib don’t have models yet (I think) for this, I’m making direct calls using get, for example:

return getInstance().then(d2 => d2.Api.getApi().get(“events?program=jqKm7VLgdzL”))

This works perfectly, I see the query go through the network view, and the values get back

Now I’m trying a event analytics query:

return getInstance().then(d2 => d2.Api.getApi().get("/25/analytics/events/query/jqKm7VLgdzL?stage=tbLC6IHktf0&dimension:ou:VAPI4p81HAz;LEVEL-6&displayProperty=NAME"));

And this show an error in the console with “Server connection failed for API request”

I’ve ran the query through the browser & Postman without any problems. I’ve debugged, the authorization header is correct.

Any clue what could go wrong there?

Thanks!

Martin

···

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Martin, I found one problem, possibly 2 with your code.
The first one is with the dimension parameter you're passing.

It should be:

dimension=ou:VAPI4p81HAz;LEVEL-6

instead of:

dimension:ou:VAPI4p81HAz;LEVEL-6

The second problem is URL encoding, specifically the ou dimension
query parameter.
The response I get in this case is "409: Dimension ou is present in
query without any valid dimension options."

It's better to pass the query parameters as a object in the 2nd
parameter of the get, so that the Api class takes care of all the URL
encoding, like this:

d2.Api.getApi().get('analytics/events/query/jqKm7VLgdzL', {
    stage: 'tbLC6IHktf0',
    dimension: 'ou:VAPI4p81HAz;LEVEL-6',
    displayProperty: 'NAME'
});

Once I do this, I get a different error about missing start and end
date, which is ok since this endpoint requires those parameters:
https://docs.dhis2.org/master/en/developer/html/webapi_event_analytics.html#webapi_event_analytics_request_query_parameters

Hope this helps,

···

On Wed, Feb 21, 2018 at 11:31 AM, Martin Van Aken <martin@joyouscoding.com> wrote:

Now I'm trying a event analytics query:

return getInstance().then(d2 =>
d2.Api.getApi().get("/25/analytics/events/query/jqKm7VLgdzL?stage=tbLC6IHktf0&dimension:ou:VAPI4p81HAz;LEVEL-6&displayProperty=NAME"));

And this show an error in the console with "Server connection failed for
API request"

I've ran the query through the browser & Postman without any problems. I've
debugged, the authorization header is correct.

Any clue what could go wrong there?

--
Edoardo Sabadelli
DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org

You are correct for the error message - now putting back a period means having multiple dimension’s - is there any way to put multiple dimension parameters through the object params? I agree this is much better than using a long query string, but just using an array as value does not work - I tried something like:

return getInstance().then(d2 =>
d2.Api.getApi().get(‘analytics/events/query/jqKm7VLgdzL’, {
stage: ‘tbLC6IHktf0’,
dimension: [‘ou:VAPI4p81HAz;LEVEL-6’,‘xxx’],
displayProperty: ‘NAME’
}));

but this is not working. Any clues?

Martin

···

On Wed, Feb 21, 2018 at 2:40 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Wed, Feb 21, 2018 at 11:31 AM, Martin Van Aken

martin@joyouscoding.com wrote:

Now I’m trying a event analytics query:

return getInstance().then(d2 =>

d2.Api.getApi().get("/25/analytics/events/query/jqKm7VLgdzL?stage=tbLC6IHktf0&dimension:ou:VAPI4p81HAz;LEVEL-6&displayProperty=NAME"));

And this show an error in the console with "Server connection failed for

API request"

I’ve ran the query through the browser & Postman without any problems. I’ve

debugged, the authorization header is correct.

Any clue what could go wrong there?

Martin, I found one problem, possibly 2 with your code.

The first one is with the dimension parameter you’re passing.

It should be:

dimension=ou:VAPI4p81HAz;LEVEL-6

instead of:

dimension:ou:VAPI4p81HAz;LEVEL-6

The second problem is URL encoding, specifically the ou dimension

query parameter.

The response I get in this case is "409: Dimension ou is present in

query without any valid dimension options."

It’s better to pass the query parameters as a object in the 2nd

parameter of the get, so that the Api class takes care of all the URL

encoding, like this:

d2.Api.getApi().get(‘analytics/events/query/jqKm7VLgdzL’, {

stage: 'tbLC6IHktf0',

dimension: 'ou:VAPI4p81HAz;LEVEL-6',

displayProperty: 'NAME'

});

Once I do this, I get a different error about missing start and end

date, which is ok since this endpoint requires those parameters:

https://docs.dhis2.org/master/en/developer/html/webapi_event_analytics.html#webapi_event_analytics_request_query_parameters

Hope this helps,

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Unfortunately using get() directly does not allow for a list as value
for query parameters.
Only the filter parameter supports an array of values in the form you
tried above.

That's one of the problems that the code for supporting analytics
requests addresses.
You can have a peek at this branch, which we're going to merge into
master soon as it is used by the new Maps app to be released.

If you can wait some time, I would suggest to use d2.analytics once is
in master.

But, after some more testing, I figured the error I mentioned "409:
Dimension ou is present in
query without any valid dimension options." is not due to encoding
problems but to the fact that in my orgunit tree I don't have LEVEL-6.
So your initial query should work fine (just the ":" was wrong), you
can add more dimension parameters in the query string.

Still it will be much easier to build analytics requests with d2.analytics.

···

On Thu, Feb 22, 2018 at 9:39 AM, Martin Van Aken <martin@joyouscoding.com> wrote:

You are correct for the error message - now putting back a period means
having multiple dimension's - is there any way to put multiple dimension
parameters through the object params? I agree this is much better than using
a long query string, but just using an array as value does not work - I
tried something like:

return getInstance().then(d2 =>
          d2.Api.getApi().get('analytics/events/query/jqKm7VLgdzL', {
            stage: 'tbLC6IHktf0',
            dimension: ['ou:VAPI4p81HAz;LEVEL-6','xxx'],
            displayProperty: 'NAME'
        }));

but this is not working. Any clues?

--
Edoardo Sabadelli
DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

···

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli <edoardo@dhis2.org> wrote:

Still it will be much easier to build analytics requests with d2.analytics.

--
Edoardo Sabadelli
DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org

Great! Not sure I’ll be able to upgrade there this being said. What DHIS2 version are supported by this D2 version?

Martin

···

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

I guess it depends on which version of DHIS2 you're running.
The specific analytics/geofeature stuff is all new, so no problem with those.
Sorry I don't have a good answer.
Perhaps some backend dev can comment here.

···

On Fri, Feb 23, 2018 at 12:44 PM, Martin Van Aken <martin@joyouscoding.com> wrote:

Great! Not sure I'll be able to upgrade there this being said. What DHIS2
version are supported by this D2 version?

--
Edoardo Sabadelli
DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org

Hello again Edoardo & d2 team,

I just tested the d2 29x version for the analytics. My problem is I don’t manage to make the simplest example work. I took an analytics query working in the REST API and tried to convert it to d2:

getAnalytics() {

return getInstance().then(d2 => {

  const req = d2.analytics.request()

    .withProgram('jqKm7VLgdzL')

    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])

    .addPeriodDimension([2016, 2017, 2018])

    .addOrgUnitDimension(['UpjTv540YGw']);

  d2.analytics.events.getQuery(req).then(console.log)

});

}

(this is closely following the example here: http://dhis2.github.io/d2/module-analytics.AnalyticsEvents.html)

This fails with a “Cannot call a class as a function AnalyticsRequest.js:25” message, on the very first line about the request (looks like request() is not returning what it expect). Any clue?

Martin

···

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Hi Martin

I don’t see the “new” in the code you posted.

It should be:

const req = new d2.analytics.request() …

···

On Feb 28, 2018 3:21 PM, “Martin Van Aken” martin@joyouscoding.com wrote:

Hello again Edoardo & d2 team,

I just tested the d2 29x version for the analytics. My problem is I don’t manage to make the simplest example work. I took an analytics query working in the REST API and tried to convert it to d2:

getAnalytics() {

return getInstance().then(d2 => {
  const req = d2.analytics.request()
    .withProgram('jqKm7VLgdzL')
    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])
    .addPeriodDimension([2016, 2017, 2018])
    .addOrgUnitDimension(['UpjTv540YGw']);
  d2.analytics.events.getQuery(req).then(console.log)
});

}

(this is closely following the example here: http://dhis2.github.io/d2/module-analytics.AnalyticsEvents.html)

This fails with a “Cannot call a class as a function AnalyticsRequest.js:25” message, on the very first line about the request (looks like request() is not returning what it expect). Any clue?

Martin

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org


**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Ok, sorry, figure it out, just require a “new” as Request is a class:

const req = new d2.analytics.request()

    .withProgram('jqKm7VLgdzL')

    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])

    .addPeriodDimension([2016, 2017, 2018])

    .addOrgUnitDimension(['UpjTv540YGw']);

But this falls back to the same problem as before - getting a server error (“uncaught exception: Server connection failed for API request:”) - despite the exact same request working as a REST call.

Martin

···

On Wed, Feb 28, 2018 at 3:20 PM, Martin Van Aken martin@joyouscoding.com wrote:

Hello again Edoardo & d2 team,

I just tested the d2 29x version for the analytics. My problem is I don’t manage to make the simplest example work. I took an analytics query working in the REST API and tried to convert it to d2:

getAnalytics() {

return getInstance().then(d2 => {
  const req = d2.analytics.request()
    .withProgram('jqKm7VLgdzL')
    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])
    .addPeriodDimension([2016, 2017, 2018])
    .addOrgUnitDimension(['UpjTv540YGw']);
  d2.analytics.events.getQuery(req).then(console.log)
});

}

(this is closely following the example here: http://dhis2.github.io/d2/module-analytics.AnalyticsEvents.html)

This fails with a “Cannot call a class as a function AnalyticsRequest.js:25” message, on the very first line about the request (looks like request() is not returning what it expect). Any clue?

Martin

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org


**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Hi,

Thanks, looks like our mails passed each other. You are right, but the “new” was missing from the doc too hence my mistake - my thanks again for your followup!

Martin

···

On Wed, Feb 28, 2018 at 4:03 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Hi Martin

I don’t see the “new” in the code you posted.

It should be:

const req = new d2.analytics.request() …


Edoardo Sabadelli
Software developer, DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org

On Feb 28, 2018 3:21 PM, “Martin Van Aken” martin@joyouscoding.com wrote:

Hello again Edoardo & d2 team,

I just tested the d2 29x version for the analytics. My problem is I don’t manage to make the simplest example work. I took an analytics query working in the REST API and tried to convert it to d2:

getAnalytics() {

return getInstance().then(d2 => {
  const req = d2.analytics.request()
    .withProgram('jqKm7VLgdzL')
    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])
    .addPeriodDimension([2016, 2017, 2018])
    .addOrgUnitDimension(['UpjTv540YGw']);
  d2.analytics.events.getQuery(req).then(console.log)
});

}

(this is closely following the example here: http://dhis2.github.io/d2/module-analytics.AnalyticsEvents.html)

This fails with a “Cannot call a class as a function AnalyticsRequest.js:25” message, on the very first line about the request (looks like request() is not returning what it expect). Any clue?

Martin

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org


**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

Oops!
Will fix the documentation.

Thanks for testing :wink:

···

On Feb 28, 2018 4:08 PM, “Martin Van Aken” martin@joyouscoding.com wrote:

Hi,

Thanks, looks like our mails passed each other. You are right, but the “new” was missing from the doc too hence my mistake - my thanks again for your followup!

Martin

On Wed, Feb 28, 2018 at 4:03 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Hi Martin

I don’t see the “new” in the code you posted.

It should be:

const req = new d2.analytics.request() …


Edoardo Sabadelli
Software developer, DHIS 2
University of Oslo
edoardo@dhis2.org
http://www.dhis2.org


**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com

On Feb 28, 2018 3:21 PM, “Martin Van Aken” martin@joyouscoding.com wrote:

Hello again Edoardo & d2 team,

I just tested the d2 29x version for the analytics. My problem is I don’t manage to make the simplest example work. I took an analytics query working in the REST API and tried to convert it to d2:

getAnalytics() {

return getInstance().then(d2 => {
  const req = d2.analytics.request()
    .withProgram('jqKm7VLgdzL')
    .addDataDimension(['fyKddt8DF3P', 'RH9knJBq3gv', 'GbtVi9hJhl1', 'pCU50gRMGQh', 'el1mbPDIDSD', 'sn3PEvqjGPp', 'jsZgVNf1fuR'])
    .addPeriodDimension([2016, 2017, 2018])
    .addOrgUnitDimension(['UpjTv540YGw']);
  d2.analytics.events.getQuery(req).then(console.log)
});

}

(this is closely following the example here: http://dhis2.github.io/d2/module-analytics.AnalyticsEvents.html)

This fails with a “Cannot call a class as a function AnalyticsRequest.js:25” message, on the very first line about the request (looks like request() is not returning what it expect). Any clue?

Martin

On Fri, Feb 23, 2018 at 12:31 PM, Edoardo Sabadelli edoardo@dhis2.org wrote:

On Thu, Feb 22, 2018 at 10:14 AM, Edoardo Sabadelli edoardo@dhis2.org wrote:

Still it will be much easier to build analytics requests with d2.analytics.

Support for analytics and geofeatures requests in d2 is out!

d2@29.0.2

Check it out!

Edoardo Sabadelli

DHIS 2

University of Oslo

edoardo@dhis2.org

http://www.dhis2.org


**Martin Van Aken - **Freelance Enthusiast Developer

Mobile : +32 486 899 652

Follow me on Twitter : @martinvanaken

Call me on Skype : vanakenm

Hang out with me : martin@joyouscoding.com

Contact me on LinkedIn : http://www.linkedin.com/in/martinvanaken

Company website : www.joyouscoding.com