# Explanation

The following provides a brief explanation of the Inrupt’s JavaScript client libraries usage in the [](https://docs.inrupt.com/sdk/javascript-sdk/tutorial "mention") application code.

## Login Code

The example uses Inrupt’s `@inrupt/solid-client-authn-browser` library to log in. `@inrupt/solid-client-authn-browser` is for **client-side code only** .

For applications implementing [Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps) :

1. The application starts the login process by sending the user to the user’s Solid Identity Provider.
2. The user logs in to the Solid Identity Provider.
3. The Solid Identity Provider sends the user back to your application, where the application handles the returned authentication information to complete the login process.

<figure><img src="https://2584838151-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLMLxFYifBOpjrf8rQMX1%2Fuploads%2Fgit-blob-207f8c5cf3aef0f5dea5f8a1e9e63cc211e63e67%2Flogin-flow.png?alt=media" alt=""><figcaption></figcaption></figure>

### Import

The application uses various objects from `@inrupt/solid-client-authn-browser` to log in.

```javascript
import {
  login,
  handleIncomingRedirect,
  getDefaultSession,
  fetch
} from "@inrupt/solid-client-authn-browser";
```

### Start Login

The application starts the login process by calling [login()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#login) with the following options:

<table><thead><tr><th width="155.33203125"></th><th></th></tr></thead><tbody><tr><td><strong><code>oidcIssuer</code></strong></td><td><p>The URL of the user’s Solid Identity Provider. The function<br>sends the user to this URL to log in.<br>In this example, it is set to the value selected by the user.</p><div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>If you are not using <a href="../../../podspaces/podspaces">PodSpaces</a>, modify the <code>select-idp</code> options in the example’s <code>index.html</code> .</p></div></td></tr><tr><td><strong><code>redirectUrl</code></strong></td><td><p>The URL where the user, after logging in, will be redirected in order to finish the login process.</p><div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>The <strong><code>redirectUrl</code></strong> value should not change with application routes or hash or query parameters.</p></div><p>In this example, it is set to <code>new URL("/", window.location.href).toString()</code> (i.e., the root URL of this<br>application <code>https://localhost:8080/</code>).</p><p>Alternatively, the example could have explicitly specified the <code>index.html</code> as the <code>redirectURL</code>; i.e., <code>new URL("/index.html", window.location.href).toString()</code>.</p></td></tr><tr><td><strong><code>clientName</code></strong></td><td>A user-friendly application name to be passed to the Solid<br>Identity Provider. The value is displayed in the Identity<br>Provider’s Access Request approval window.</td></tr></tbody></table>

```javascript
function loginToSelectedIdP() {
  const SELECTED_IDP = document.getElementById("select-idp").value;
  return login({
    oidcIssuer: SELECTED_IDP,
    redirectUrl: new URL("/", window.location.href).toString(),
    clientName: "Getting started app"
  });
}
```

The [login()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#login) function sends the user to the Solid Identity Provider specified in `oidcIssuer` . Once the user logs in with the Identity Provider, the user is redirected back to the specified `redirectUrl` to finish the login process .

### Finish Login

Once logged in at the Solid Identity Provider, the user is redirected back to the `redirectUrl` specified at the start of the login process (i.e., in the `login()` function call). The page at this `redirectUrl` calls [handleIncomingRedirect()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#getdefaultsession) to complete the login process.

In the example, the page calls `handleRedirectAfterLogin()` method, which, in turn, calls the [handleIncomingRedirect()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#getdefaultsession) :

<pre class="language-javascript"><code class="lang-javascript">
// When redirected after login, finish the process by retrieving session information.
async function handleRedirectAfterLogin() {
<strong>  await handleIncomingRedirect(); // no-op if not part of login redirect
</strong>
  const session = getDefaultSession();
  if (session.info.isLoggedIn) {
    // Update the page with the status.
    document.getElementById("myWebID").value = session.info.webId;
    // Enable Read button to read Pod URL
    buttonRead.removeAttribute("disabled");
  }
}
// The example has the login redirect back to the root page.
// The page calls this method, which, in turn, calls handleIncomingRedirect.
handleRedirectAfterLogin();
</code></pre>

The [handleIncomingRedirect()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#getdefaultsession) function collects the information provided by the Identity Provider. [handleIncomingRedirect()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#getdefaultsession) is a no-op if called outside the login processs.

For more information on using the library to authenticate, see [authentication](https://docs.inrupt.com/sdk/javascript-sdk/authentication "mention").

## Get Pods Code

The example uses Inrupt’s `solid-client` library to return the Pods associated with a WebID.

### Import

The application uses various objects from `@inrupt/solid-client` . Additional import objects are displayed for the other read and write operations used in the application.

```javascript
import {
  addUrl,
  addStringNoLocale,
  createSolidDataset,
  createThing,
  getPodUrlAll,
  getSolidDataset,
  getThingAll,
  getStringNoLocale,
  removeThing,
  saveSolidDatasetAt,
  setThing
} from "@inrupt/solid-client";
import { SCHEMA_INRUPT, RDF, AS } from "@inrupt/vocab-common-rdf";
```

### Get Pods

The application uses [getPodUrlAll](https://inrupt.github.io/solid-client-js/modules/profile_webid.html#getpodurlall) to retrieve the Pod URLs (i.e., the value stored under `http://www.w3.org/ns/pim/space#storage` ) in the user’s profile.

```javascript
const webID = document.getElementById("myWebID").value;
const mypods = await getPodUrlAll(webID, { fetch: fetch });
```

* For more information on properties of `Things` , and see [structured-data-rdf-resources](https://docs.inrupt.com/reference/rdf/structured-data-rdf-resources "mention").
* For more information on read operations, see [read-and-write-rdf-data](https://docs.inrupt.com/sdk/javascript-sdk/read-and-write-rdf-data "mention").

## Write Reading List

### Import

The application uses various objects from `solid-client` and `vocab-common-rdf` libraries to write data to your Pod. Additional import objects are shown for read profile operations.

```javascript
import {
  addUrl,
  addStringNoLocale,
  createSolidDataset,
  createThing,
  getPodUrlAll,
  getSolidDataset,
  getThingAll,
  getStringNoLocale,
  removeThing,
  saveSolidDatasetAt,
  setThing
} from "@inrupt/solid-client";
import { SCHEMA_INRUPT, RDF, AS } from "@inrupt/vocab-common-rdf";
```

### Create Reading List SolidDataset

The application uses [getSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#getsoliddataset) to retrieve an existing reading list from the URL.

* If found, the application uses [removeThing](https://inrupt.github.io/solid-client-js/modules/thing_thing.html#removething) to clear the reading list by removing all titles from the list.
* If not found (i.e., errors with [404](https://docs.inrupt.com/sdk/error-codes#id-404-not-found)), the application uses [createSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#createsoliddataset) to create a new SolidDataset (i.e., the reading list).

```javascript
  let myReadingList;
  try {
    // Attempt to retrieve the reading list in case it already exists.
    myReadingList = await getSolidDataset(readingListUrl, { fetch: fetch });
    // Clear the list to override the whole list
    let items = getThingAll(myReadingList);
    items.forEach((item) => {
      myReadingList = removeThing(myReadingList, item);
    });
  } catch (error) {
    if (typeof error.statusCode === "number" && error.statusCode === 404) {
      // if not found, create a new SolidDataset (i.e., the reading list)
      myReadingList = createSolidDataset();
    } else {
      console.error(error.message);
    }
  }
```

{% hint style="info" %}
As an alternative to fetching an existing reading list and removing all titles from the list, you can instead attempt to [deleteSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#deletesoliddataset) first, and then use [createSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#createsoliddataset) .
{% endhint %}

### Add Items (Things) to Reading List

For each title entered by the user:

* The application uses [createThing](https://inrupt.github.io/solid-client-js/modules/thing_thing.html#creatething) to create a new reading item Thing.
  * The application specifies the Thing’s name (optional) during its instantiation. Typically, a Thing’s URL is its SolidDataset URL (which ends with a `/`) appended with `#` and the Thing’s name; in this case:
    * `${podURL}getting-started/readingList/myList#title1`,
    * `${podURL}getting-started/readingList/myList#title2`, etc.
* To the item, the application uses the following functions to add specific data:
  * [addUrl](https://inrupt.github.io/solid-client-js/modules/thing_add.html#addurl) to add the `http://www.w3.org/1999/02/22-rdf-syntax-ns#type` property with the URL value `https://www.w3.org/ns/activitystreams#Article`\
    The example uses the `RDF.type` and `AS.Article` convenience objects to specify the aforementioned property and value.
  * [addStringNoLocale](https://inrupt.github.io/solid-client-js/modules/thing_add.html#addstringnolocale) to add the `https://schema.org/name` property with the string value set to one of the entered titles.\
    The example uses the `SCHEMA_INRUPT.name` convenience object for the aforementioned property.
* Then, the application uses [setThing](https://inrupt.github.io/solid-client-js/modules/thing_thing.html#setthing) to add the item to the SolidDataset (i.e., the reading list).

```javascript
  let i = 0;
  titles.forEach((title) => {
    if (title.trim() !== "") {
      let item = createThing({ name: "title" + i });
      item = addUrl(item, RDF.type, AS.Article);
      item = addStringNoLocale(item, SCHEMA_INRUPT.name, title);
      myReadingList = setThing(myReadingList, item);
      i++;
    }
  });
```

The `solid-client` library’s functions (such as the various add/set functions) do not modify the objects that are passed in as arguments. Instead, the library’s functions return a new object with the requested changes.

### Save Reading List (SolidDataset)

{% hint style="info" %}
For the sake of simplicity and brevity, this getting started guide hardcodes the SolidDataset URL. In practice, you should add a link to this resource in your profile that applications can follow.
{% endhint %}

Use [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetat) to save the reading list to `<PodURL>getting-started/readingList/myList` . [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetat) creates any intermediate folders/containers as needed.

```javascript
let savedReadingList = await saveSolidDatasetAt(
  readingListUrl,
  myReadingList,
  { fetch: fetch }
);
```

{% hint style="info" %}
The `solid-client` library also provides the [saveSolidDatasetInContainer](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetincontainer) . However, unlike [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetat) which creates any intermediate folders/containers as needed, [saveSolidDatasetInContainer](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetincontainer) requires that the specified destination container already exists.
{% endhint %}

Upon successful save, [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetat) returns a SolidDataset whose state reflects the data that was sent to be saved.

See also [Create vs. Update Operations](https://docs.inrupt.com/sdk/read-and-write-rdf-data#save-considerations).

### Verify the Save Operation

The save operation returns the SolidDataset (the reading list) whose state reflect the data that was sent to be saved. The `savedReadingList` may not accurately reflect the saved state of the data if concurrent operations have modified additional fields.

To ensure you have the latest data, the tutorial uses [getSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#getsoliddataset) again after saving the data.

```javascript
savedReadingList = await getSolidDataset(readingListUrl, { fetch: fetch });
let items = getThingAll(savedReadingList);
let listcontent = "";
for (let i = 0; i < items.length; i++) {
  let item = getStringNoLocale(items[i], SCHEMA_INRUPT.name);
  if (item !== null) {
    listcontent += item + "\n";
  }
}
document.getElementById("savedtitles").value = listcontent;
```

The application uses `SCHEMA_INRUPT.name` convenience object from the `vocab-common-rdf` library to specify the property to retrieve.
