Next.js: Using setInterval() for getInitialProps()?

Created on 17 Feb 2018  路  9Comments  路  Source: vercel/next.js

Hi everyone!

I am trying to call getInitialProps() every 1 second. However, having a hard time crafting it out. I am sorry if this is a noob question as I am still learning Next.js.

Should I do this using getInitialProps()? I was thinking that maybe I can do this using componentDidMount(). But after reading this link I really do want to call the API using getInitialProps().

class Index extends React.Component {
  static async getInitialProps() {
    const res = await Axios.get(
      "https://www.metaweather.com/api/location/44418/"
    );
    return { data: res.data };
  }

  render() {
    return (
      <div>
        <h1>Current Time</h1> <h2> {this.props.data.time} </h2>
      </div>
    );
  }
}

export default Index

Thanks for looking into this question.

All 9 comments

Are you trying to update the time by calling that api every second?

If you want to refresh the data every second (which I'd ask myself if it's really necessary). But then you'd get the initial data with getInitialProps, and then after on componentDidMount you could start an interval to keep refreshing. But that shouldn't call getInitialProps in the interval though.

@TaroWong, hi man, if you wanna use getInitialProps by setInterval, then you should reload your page by that interval, bcs getInitialProps calling is just once - at page initial loading.
If you need fetch some data by interval, then use setInterval in componentDudMount.

@thomhos , @JerryCauser , thanks for replying and clarifying! I was just experimenting with getInitialProps. Totally forgot about "getInitialProps calling is just once - at page initial loading"

馃槂

1 question regarding file structure

Should I create a component just to grab data from the API and push it to index page or is it better to just create componentDidMount in index.js?

Or none of them makes any differences in performance?

I wouldn't worry about performance until it becomes a (measurable) problem. Keep it simple, and if you feel it can be done more efficient, test it and then improve.

early stage complexity doesn't make for a maintainable project in the long term :)

Hi @thomhos , I am sorry I do have another question.

Using componentWillMount gives me CORS error because I guess there was some SSR at the back done by getInitialProps.

Are there any ways that I could use the getInitialProps() 's router to route my API call? I tried using withRouter

import react from "react";
import axios from "axios";
import { withRouter } from "next/router";

class Weatherboy extends React.Component {
  componentWillMount() {
    const res = axios.get("https://www.metaweather.com/api/location/44418/");
    return { data: res.data };
  }

  render() {
    return <div>{this.props.data.time}</div>;
  }
}

export default withRouter(Weatherboy);

I have a feeling that withRouter is not used for cases like this. Sorry for spamming noobie questions over here.

getInitialProps is awesome. If there are docs of how it works behind the scenes will be amazing as it totally solves the CORS problem without the need of proxying an external API.

Yeah server side you won't have that issue, it's probably coming from your OPTIONS request right?

You could setup a proxy by using a custom server (see the example custom server on how to set that up). A proxy from your own api endpoint to that url should be straightforward.

Hi @thomhos

Firstly, I would like to apologize for posting questions instead of issues. Currently, I am using a different API which has the same CORS issues.

I have tried to setup custom headers to fix the problem but it does not work or change anything by using the cors package by Express.

I did setting the headers in the fetch method inside the react component but the results are the same.

server.js

const express = require("express");
const next = require("next");
const cors = require("cors");

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app
  .prepare()
  .then(() => {
    const server = express();

    const corsOptions = {
      origin: "http://localhost:3000",
      methods: ["POST"],
      allowedHeaders: [
        "Origin",
        "X-Requested-With",
        "Content-Type",
        "Accept",
        "Authorization"
      ],
      credentials: true
    };

    server.use(cors(corsOptions));

    server.get("*", (req, res) => {
      return handle(req, res);
    });

    server.listen(3000, err => {
      if (err) throw err;
      console.log("Live on http://localhost:3000");
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

index.js

import React from "react";
import "isomorphic-unfetch";
import Bittrex from "../components/Bittrex";

class Index extends React.Component {
  static async getInitialProps() {
    const res = await fetch(
      "https://bittrex.com/api/v1.1/public/getmarketsummaries"
    );
    const json = await res.json();
    return { bid: json.result[0].Bid };
  }

  render() {
    return (
      <div>
        <h1>Testing CORS</h1>
        <h2>{this.props.bid}</h2>
        <p>Working with "getInitialProps"</p>
        <Bittrex />
      </div>
    );
  }
}

export default Index;

Bittrex.js

import React from "react";

class Bittrex extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      lol: ""
    };
  }

  componentDidMount() {
    fetch("https://bittrex.com/api/v1.1/public/getmarketsummaries")
      .then(res => res.json())
      .then(result => {
        this.setState({
          lol: result[114].MarketName
        });
      });
  }

  render() {
    return (
      <div>
        <h3>React Component</h3>
        <p>{this.state.lol} - Market name will be displayed on the left</p>
      </div>
    );
  }
}

export default Bittrex;

Thanks for looking into this question.

Hi Taro,

I suggest you post these questions on stack overflow, as it's not directly related to nextjs. Also there's a slack channel available to ask questions on nextjs.

But you should realise that getInitialProps is called both serverside and possibly later some time on client side (if you navigate to a page that has 'getInitialProps' defined. This means it can be executed both from the server side or client side. To avoid CORS issues you could setup an api for yourself (separate from the frontend) which acts as a proxy.

I see you're using bittrex, maybe this might be interesting: https://github.com/ccxt/ccxt

Good luck!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

YarivGilad picture YarivGilad  路  3Comments

knipferrc picture knipferrc  路  3Comments

swrdfish picture swrdfish  路  3Comments

pie6k picture pie6k  路  3Comments

havefive picture havefive  路  3Comments