1

So, I have an appwrite and sveltekit application running. This is my first time using both. I have managed to set up appwrite sdk and connected to database and have api data stream coming in when I log it. Here is the data I get from appwrite in the console.

Now I want to display this data and I am not sure where I am missing it. The info I find is for consuming REST api data and not really for data coming in from appwrite. Here is my code on the svelte side:

<script>

import { Client, Databases } from "appwrite";

const client = new Client();

const databases = new Databases(client);

client
    .setEndpoint('http://localhost/v1') // Your API Endpoint
    .setProject('63d89956ac3d018e22ff') // Your project ID
;

const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

promise.then(function (response) {
    console.log(response); // Success
   
}, function (error) {
    console.log(error); // Failure
});
let appdata = promise;

</script>
  {#each appdata.documents as front}<p>{front.content}</p>{/each}
<div class="hero min-h-screen" style="background-image: url(../src/images/header_front.png);">
    <div class="hero-overlay bg-opacity-60"></div>
    <div class="hero-content text-center text-neutral-content">
      <div class="max-w-md">
        <h1 class="mb-5 text-5xl font-bold prose">Welcome to Nafuna!</h1>
        <p class="mb-5 prose">

I know I am missing someting in how svelte displays this but please assist!

I tried to convert the data from the original const into let because had read that svelte displays from let but that didnt work either.

EDIT: I have included a return as suggested here and I still cant get the data to display so I thought I would paste the code here again with the updates:

<script lang="ts">

import { Client, Databases } from "appwrite";

const client = new Client();

const databases = new Databases(client);

client
    .setEndpoint('http://localhost/v1') // Your API Endpoint
    .setProject('63d89956ac3d018e22ff') // Your project ID
;

const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

promise.then(function (response) {
    console.log(response); // Success
    return response;
   
}, function (error) {
    console.log(error); // Failure
    throw error;
});

// let appdata;
// appdata = response;

</script>

  {#each appdata as front}<p>{front.documents.content}</p>{/each}
  • Remove the `let appdata` and try wrapping the `#each` with an `#await`block `{#await promise then appdata}` https://svelte.dev/tutorial/await-blocks – Corrl Feb 07 '23 at 11:02
  • Hi there, So I have tried this out and didnt really get far. Had a 500 error. My question is, you specify appdata in the await tag but if we have removed it already, would we be able to reference it? – Nqobizitha Mlilo Feb 08 '23 at 06:13
  • If you're getting a 500 error from Appwrite, you should look at the docker logs for the appwrite container (`docker compose logs appwrite`) to see the details for the 500 error. – Steven Nguyen Feb 09 '23 at 23:20

2 Answers2

0

Your

promise.then(function (response) {
    console.log(response); // Success
   
}, function (error) {
    console.log(error); // Failure
});

may be causing a problem because it changes the promise to resolve to nothing. You could try to make sure it returns the actual data:

promise.then(function (response) {
    console.log(response); // Success
    return response;
   
}, function (error) {
    console.log(error); // Failure
    throw error;

});
Steven Nguyen
  • 452
  • 4
  • 4
  • Hi there, this makes sense. I had not returned the value. I have done so now and I havent got the data to display but I eliminated a lot of the errors. I am updating my original post with new code – Nqobizitha Mlilo Feb 08 '23 at 06:14
  • Looking at your updated code, you're using `appdata`, but it isn't defined. Also, you need to share the errors you're getting. – Steven Nguyen Feb 09 '23 at 23:21
0

Here's a way without #await in case the whole appdata object is needed
reactive variable - ternary operator - ?. - ??

<script lang="ts">
    import { Client, Databases } from "appwrite";
    const client = new Client();
    const databases = new Databases(client);

    let appdata;
    $: documents = appdata ? appdata.documents : [] //or  appdata?.documents ?? []

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('63d89956ac3d018e22ff') // Your project ID
    ;

    const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

    promise.then(function (response) {
        console.log(response); // Success
        appdata = response

    }, function (error) {
        console.log(error); // Failure
        throw error;
    });

</script>

{#each documents as front}
<p>
    {front.content}
</p>
{/each}

In case it's fine to only use the documents

<script lang="ts">
    import { Client, Databases } from "appwrite";
    const client = new Client();
    const databases = new Databases(client);

    let documents = [];

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('63d89956ac3d018e22ff') // Your project ID
    ;

    const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

    promise.then(function (response) {
        console.log(response); // Success
        documents = response.documents

    }, function (error) {
        console.log(error); // Failure
        throw error;
    });

</script>

{#each documents as front}
<p>
    {front.content}
</p>
{/each}

Using #await to benefit from showing a message while loading and in error case (here appdata will be only available inside the :then block)

<script lang="ts">
    import { Client, Databases } from "appwrite";
    const client = new Client();
    const databases = new Databases(client);

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('63d89956ac3d018e22ff') // Your project ID
    ;

    const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

</script>

{#await promise}
    <p>...waiting</p>
{:then appdata}
    {#each appdata.documents as front}
        <p>
            {front.content}
        </p>
    {/each}
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}

Using #await with documents in component scope in case needed. Using an underscore in {:then _} as variable name indicates that the value doesn't matter and lets documents inside the #each loop point to the variable in the script tag

<script lang="ts">
    import { Client, Databases } from "appwrite";
    const client = new Client();
    const databases = new Databases(client);

    let documents = []

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('63d89956ac3d018e22ff') // Your project ID
    ;

    const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');

    promise.then(function (response) {
        console.log(response); // Success
        documents = response.documents

    }, function (error) {
        console.log(error); // Failure
        throw error;
    });

</script>

{#await promise}
    <p>...waiting</p>
{:then _}
    {#each documents as front}
        <p>
            {front.content}
        </p>
    {/each}
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}
Corrl
  • 6,206
  • 1
  • 10
  • 36
  • you're aawesome, tried the first and it worked! Data is coming through nicely. I am analyzing the code to learn better from this! Thank you – Nqobizitha Mlilo Feb 09 '23 at 23:04
  • @NqobizithaMlilo that's great :) If an answer helped with the problem, you can mark it as solved via the checkmark on the left – Corrl Feb 10 '23 at 07:04