最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - API requests in svelte - Stack Overflow

programmeradmin4浏览0评论

I'm a bit new to svelte and javascript. I'm trying to build a page with many API ponents from external websites and I struggle a bit. I don't really know where to put the different bits of code. The closer I am no is this :

in Bapi.svelte (ponent) :

<script>

    function getSomething() {
        fetch('getapi')
    }
</script>

<h1>get something here</h1>
<button on:click={getSomething}>Get !</button>

in server.js (routes) :

import sirv from 'sirv';
import express from 'express';
import pression from 'pression';
import * as sapper from '@sapper/server';

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';

const app = express();

app.use(express.urlencoded())
app.use(express.json())

    app.use(
        pression({ threshold: 0 }),
        sirv('static', { dev }),
        sapper.middleware()
    )
    .listen(PORT, err => {
        if (err) console.log('error', err);
});

in getapi.js (routes) :

export function get(res, req, next) {
    var resp = app.endpoints.coinbasepro.get('/coinbase-products');
    console.log(resp)
}

When I click on get i have this error : app is not defined. I maybe has something to do with the scope but after moving the variable around for a while I need some help because I am stuck at this point. Thanks

I'm a bit new to svelte and javascript. I'm trying to build a page with many API ponents from external websites and I struggle a bit. I don't really know where to put the different bits of code. The closer I am no is this :

in Bapi.svelte (ponent) :

<script>

    function getSomething() {
        fetch('getapi')
    }
</script>

<h1>get something here</h1>
<button on:click={getSomething}>Get !</button>

in server.js (routes) :

import sirv from 'sirv';
import express from 'express';
import pression from 'pression';
import * as sapper from '@sapper/server';

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';

const app = express();

app.use(express.urlencoded())
app.use(express.json())

    app.use(
        pression({ threshold: 0 }),
        sirv('static', { dev }),
        sapper.middleware()
    )
    .listen(PORT, err => {
        if (err) console.log('error', err);
});

in getapi.js (routes) :

export function get(res, req, next) {
    var resp = app.endpoints.coinbasepro.get('/coinbase-products');
    console.log(resp)
}

When I click on get i have this error : app is not defined. I maybe has something to do with the scope but after moving the variable around for a while I need some help because I am stuck at this point. Thanks

Share Improve this question asked Jul 22, 2020 at 22:56 James ChenJames Chen 891 silver badge9 bronze badges 1
  • 3 The app variable is only defined within server.js. You would have to explicitly export it from there and import it where needed in your server routes before you can make use of it. On top of that, I don't see the endpoints.coinbasepro.get() method you're trying to access on the app object defined anywhere. Where is it ing from? – Thomas Hennes Commented Jul 23, 2020 at 2:16
Add a ment  | 

3 Answers 3

Reset to default 2

Well, as you are using sapper, it works a bit differently than when using pure svelte.

Your code runs on the client as well as on the server, but you only have access to fetch in the client code (it runs only in the browser). To circumvent this, you have access to this.fetch. So what you should do is use the preload function in a context module, passing the result to the ponent who needs it.

// Bapi.svelte
<script context="module">
  export async function preload() {
    const res = await this.fetch(`getapi`, {
        credentials: 'include'
    });

    // ...
    // Pass the api result to your ponent
      return { data: res }
    }
</script>

// This is your ponent, it lives in the same file
<script>
// You can get the data from the context module here
export let data
</script>

Context module and ponent are declared in the same file, but the context is not part of the ponent itself, the code in it runs before the ponent is created. You may have to use JSON.stringify(res) on the result, depending how it is structured.

Your main problem seems to be in the server as pointed out by @ThomasHennes, nothing directly to do with svelte or sapper.

I also believe you're not posting the plete code to continue helping you in this regard.


Leaving that aside, you still have a problem in your Svelte ponent, it is not Sapper-patible, you cannot use fetch inside the script of the ponent, as pointed out by @Gh05d, because when the server is rendering, that code will run in NodeJs, and NodeJs does not have fetch.


This is the sapper-patible version of your Svelte ponent

<script>
    import { onMount } from 'svelte';

    let getSomething;
    onMount(()=>{
        getSomething = () =>{
            fetch('getapi')
        }
    });
</script>

<h1>get something here</h1>
<button on:click={getSomething}>Get !</button>

Any code you put inside the onMount will be executed only in the browser.

Thanks to you all for your answers ! I was using the wrong url to get the api so it wasn't helping. Eventually I used this code that worked fine for me :

in getapi.js

import Axios from "axios"
export async function get(res, req, next) {
     var resp = await Axios.get("https://api.pro.coinbase./products");
    console.log(resp)
}

in Bapi.svelte

<script>
    import {get} from "./getapi.js"
    function getSomething() {
        get()
        
    }
</script>

<h1>get something here</h1>
<button on:click={getSomething}>Get !</button>

and I moved getapi.js from routes to ponents I think it was creating a problem (but not sure)

Now I'm trying to get data from a websocket instead of the api, do you know a good crashcourse or tutorial on how to do that in svelte ?

Cheers all !!

发布评论

评论列表(0)

  1. 暂无评论