Failed to write structured data in pod by use solid-client library

I used solid-node-client’s function login my solid pod, then i try to add thing in my pod.
i use solid-client’s function saveSolidDatasetAt to save my change,but there some error as bellow
can’t i use solid-node-client and solid client like this?

(node:26232) UnhandledPromiseRejectionWarning: Error: Storing the Resource at [https://liwenjing.solidcommunity.net/public/fuxilink] failed: [401] [Unauthenticated].
The SolidDataset that was sent to the Pod is listed below.

# SolidDataset: https://liwenjing.solidcommunity.net/public/fuxilink/

## Thing: https://liwenjing.solidcommunity.net/public/fuxilink

Property: http://www.w3.org/1999/02/22-rdf-syntax-ns#type
- <http://www.w3.org/ns/ldp#BasicContainer> (URL)
- <http://www.w3.org/ns/ldp#Container> (URL)

Property: http://purl.org/dc/terms/modified
- Mon, 10 May 2021 08:54:06 GMT (datetime)

Property: http://www.w3.org/ns/ldp#contains
- <https://liwenjing.solidcommunity.net/public/A1/> (URL)

Property: http://www.w3.org/ns/posix/stat#mtime
- 1620636846.959 (decimal)

Property: http://www.w3.org/ns/posix/stat#size
- 4096 (integer)

(0 new values added / 0 values removed)

## Thing: https://liwenjing.solidcommunity.net/public/A1/

Property: http://www.w3.org/1999/02/22-rdf-syntax-ns#type
- <http://www.w3.org/ns/ldp#BasicContainer> (URL)
- <http://www.w3.org/ns/ldp#Container> (URL)
- <http://www.w3.org/ns/ldp#Resource> (URL)

Property: http://purl.org/dc/terms/modified
- Mon, 10 May 2021 08:54:41 GMT (datetime)

Property: http://www.w3.org/ns/posix/stat#mtime
- 1620636881.603 (decimal)

Property: http://www.w3.org/ns/posix/stat#size
- 4096 (integer)

(0 new values added / 0 values removed)

    at saveSolidDatasetAt (D:\solid\fuxilink_es2\node_modules\@inrupt\solid-client\dist\index.js:2520:15)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async addurl (D:\solid\fuxilink_es2\public\javascripts\nss-login.js:44:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:26232) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:26232) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

my code

var SolidNodeClient = require('solid-node-client');
var AuthNode = require('@inrupt/solid-client-authn-node');
const client = new SolidNodeClient.SolidNodeClient();
const { 
    getSolidDataset,
    saveSolidDatasetInContainer,
  getThing,
  getStringNoLocale,
  getUrlAll,
  createThing,
  setThing,
  saveSolidDatasetAt
  } = require("@inrupt/solid-client");

async function nssLogin(){
    try{
        let session = await client.login(
            {
                idp:"https://liwenjing.solidcommunity.net",
                username:"myname",
                password:"mypassword"
            }
        );
        if(session.isLoggedIn){
            let webid = await client.fetch(session.webId);
            console.log(webid);
            addurl();
        };
    } catch(e){
        console.log(e,"ERROR");
    }
}
async function getmyprofile(){
    let myDataset = await getSolidDataset("https://liwenjing.solidcommunity.net/profile/card");
    
    console.log(myDataset+'jdsaasdfjlkasjflasdjflsajlkfjalsj');
}
async function addurl(){
    let mylinkset = await getSolidDataset("https://liwenjing.solidcommunity.net/public/fuxilink");
    console.log(mylinkset);
    let linktemplate = createThing({name:'Template1'});
    console.log(linktemplate);
    mylinkset = setThing(mylinkset,linktemplate);
    console.log(mylinkset);
    await saveSolidDatasetAt("https://liwenjing.solidcommunity.net/public/fuxilink",mylinkset);

}
nssLogin();

Hi @wenjingli-qa, the error is [401] [Unauthenticated], so the request sent by saveSolidDatasetAt does not include your user credentials.

I’m not super familiar with solid-node-client, but it looks like it provides a fetch function that includes credentials. You can pass it to solid-client as an option on the third parameter, i.e. replacing

    await saveSolidDatasetAt("https://liwenjing.solidcommunity.net/public/fuxilink",mylinkset);

with

    await saveSolidDatasetAt("https://liwenjing.solidcommunity.net/public/fuxilink",mylinkset, { fetch: client.fetch });
1 Like

Yes, @Vincent is correct, the problem is that you have not told solid-client to use solid-node-client as its fetch. However, the fetch should be added slightly differently : instead of {fetch:client.fetch} you should use {fetch:client.fetch.bind(client)}.

@Vincent can the fetch be declared globally, or does it need to be added to each save/get?

Every save/get for now, though adding the ability to set it globally is on the todo list.

1 Like

@Vincent - I suggest that you use the same mechanism that rdflib does. This would mean user can 1) set global.SolidFetcher (in nodejs) / window.SolidFetcher (in browser) or 2) set the fetch by passing it in as you do with save/get but on instantiation of the fetcher not with each save/get. I can show you the code in rdflib that does this if you’re interested.

2 Likes

When in doubt, leave it to @jeffz to figure out.

1 Like