1

I just recently tried switching to d3 v5 from v4, and I am getting 401 (Unauthorized) errors every place I use d3.json. I cannot seem to figure out what changed or if this is a bug.

Here is a typical call to a random data set in v4, which works perfectly fine with the v4 library:

var url = "somedata.json";
d3.json(url, function(error, json) { console.log(json); });

I changed the code appropriately for v5 and get a 401 error:

var url = "somedata.json";
d3.json(url).then(function(data){
    console.log(data);
    });

My apologies if I did not make it clear initially that the problem is the 401 error. Apart from the promise construct, the only change was the d3 version.

I created a plunk for this and it works just fine: https://plnkr.co/edit/iTZzdc27eJaubiOJvmsi?p=preview

I am thinking the problem is a combination of the d3 v5 library with my web server (which is on a private network): IIS using Windows domain security. Since version 4 (and all previous versions) have worked great, I am thinking either something changed with d3, or I need to do something more in the request.

  • Is your JSON API protected in some way? Perhaps by a cookie? – Mark Apr 18 '18 at 00:39
  • @gerardofurtado, I re-opened this one, looks like there's more to it then not just understanding the fetch/promise change with d3 v5. – Mark Apr 18 '18 at 00:42
  • @Mark yes, you're correct,, I missed the *"I also tried..."* part. – Gerardo Furtado Apr 18 '18 at 02:13
  • 1
    I do not think my JSON API is protected. How would I know? The difference appears to be that d3 in v5 is now a wrapper around the Fetch API and I suppose since my web server requires authentication, I had to put something in there to override indications of anonymity. – Michael Larson Apr 19 '18 at 11:57

2 Answers2

2

Needed to add credential information to the request:

var url = "somedata.json";
d3.json(url, {credentials: 'same-origin'})
    .then(function(data) { console.log(data); });
    .error(function(error) { console.log(error); });

This explains the issue: Access denied under Basic Authentication

-1

Typical usage of Promises is done the following way:

doSomething().then(function(response) {
   // success
}).catch(function(error) {
   // error
});

Hence d3.json() will result in the following structure:

d3.json(url).then(function(json) {
   console.log(json);
}).catch(function(err) {
   console.log(err);
});

I've created a Plunkr using the same:

DEMO FOR d3 v5 Promises (d3.json() example)

For testing purposes, try changing the URL in the d3.json() function and you'll observe the error in the console.

Read more about promises here. Also, please go through the documentation for d3 v5 - CHANGES.

Hope this helps.

Shashank
  • 5,570
  • 1
  • 11
  • 17
  • 1
    @Gerardo Thanks. I never checked for a duplicate. My bad. Anyway, hope the example (plunkr) is useful. – Shashank Apr 17 '18 at 21:27
  • Thanks for the tip, that was the first thing I saw when I got the 401 error and tried, but still got a 401 error which is my real issue. I tried the other data fetch methods, such as d3.csv and get the same error. – Michael Larson Apr 17 '18 at 22:58
  • @Shashank No worries. At the end this was not a duplicate, OP already stated in his question that he tried the promise pattern (that's probably why you've got a downvote). – Gerardo Furtado Apr 18 '18 at 03:14
  • @GerardoFurtado At the time when the question was posted, the OP hadn't mentioned the fact that he tried the promise pattern and so I came up with this. (the downvoter mustn't have considered this). Anyway, I just read the edited question. Michael: would you mind creating a plunkr reproducing the issue? If you say it works with v4 and not with v5, that makes it something to look into. – Shashank Apr 18 '18 at 03:38
  • @Shashank if you look at the edit history it's there, in the first version. It was my mistake missing that and closing it as a duplicate – Gerardo Furtado Apr 18 '18 at 03:46
  • @GerardoFurtado If you look at the first version, the promise's `then` callback has 2 arguments `function(error, json)` which is not correct, is it? And so I came up with the typical usage of promises and how to catch an error (if any). – Shashank Apr 18 '18 at 03:51
  • Anyway, I think it's something related to accessibility (credentials) to the file. It's better to have a `catch` callback to check the error in detail. – Shashank Apr 18 '18 at 03:53