Search code examples
javascriptreactjsfetchmicrosoft-teams

How do i fetch json from a url and display json content on my js page


Im making a custom MS Teams app and in the app im trying to fetch a json from a url to then display the contents later. However, the fetch is failing. My goal is to fetch a list of data from a supplied url and then displaying it in the Tab within my teams app, which would be here: Where i want my json content to show up

As you can probably tell, i dont have any experience with javascript at all, but the custom MS teams app wants javascript...

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import React from 'react';
import './App.css';
import * as microsoftTeams from "@microsoft/teams-js";

/**
 * The 'GroupTab' component renders the main tab content
 * of your app.
 */

class Tab extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      context: {}
    }
  }

  //React lifecycle method that gets called once a component has finished mounting
  //Learn more: https://reactjs.org/docs/react-component.html#componentdidmount
  componentDidMount(){
    // Get the user context from Teams and set it in the state
    microsoftTeams.getContext((context, error) => {
      this.setState({
        context: context
      });
    });
    // Next steps: Error handling using the error object
  }

  componentDidMount() {
    fetch('http://example.com/movies.json')
      .then(response => response.json())
      .then(data => console.log(data));

  }

  render() {
      var jsondata = data; 
      let userName = Object.keys(this.state.context).length > 0 ? this.state.context['upn'] : "";

      return (
        <div>

        </div>
      );
  }
}
export default Tab;

So to sum it all up, how do i fetch my json from a url and display the content of that json on my tab.js page within teams?

Thanks in advance for any help.


Solution

  • While I can't speak to how the Teams API works, I can help you understand how to render things from a json API in your react component.

    In your componentDidMount function, your example is sending and receiving the response from the API. To render this response, we need to assign the data to your component's "state" and then use that to render it in HTML.

    This will be pretty simple. First, you need to extend your component's state, in a similar manner as you've done for context. Do this first in the constructor, where we'll declare an initial state of an empty object (I'll name it content but you can use whatever name makes most sense):

    // inside the constructor() function
    this.state = {
      context: {},
      content: {}
    }
    

    In React, we use setState to update this state object state when something changes, like on a lifecycle method such as componentDidMount. You just need to call this setState again when you want to change the state object from its initial value to something else. In our case, when we receive the data from the API.

    setState takes whatever you provide it and merges it into the state object, so you only should declare anything you want to change. Anything else not declared will remain unchanged.

    So, in componentDidMount, we can make a small change to do something with data when it arrives:

     componentDidMount() {
        fetch('http://example.com/movies.json')
          .then(response => response.json())
          .then(data => {
            this.setState({
              content: data 
            })
          });
      }
    

    This is basically saying:

    • once the component has mounted, make a call to fetch from the API
    • then, with that response, take the json from the body
    • and then, assign the json "data" into our component's state object under the key of content.

    You can then do things with this data by calling this.state.content. I'm not sure what format the data will come in, but whatever json object arrives back from the API will be stored under this.state.content.

    As an example, imagine we get a simple object back from the API that looks like this { title: "Tab title" }. It means that, on a successful call to the API, our state object will look like this:

    {
      context: "whatever you have here", // whatever you have here, I don't know this
      content: { title: "Tab title" }
    }
    

    When this state object is updated, react will trigger a new render of the component.

    So, to make it appear in our component, we need to use this state in our render function (we wrap things in curly braces if they need to be dynamically rendered rather than hardcoded):

    render() {
      return (
          //... the rest of your function
          <div>{this.state.content.title}</div>
      );
    }
    
    

    As you might have guessed, this will show the title inside a div, if the title exists.

    Eventually, you should consider handling the state of the component before that API call has resolved itself. The lifecycle method componentDidMount will be called after the component is mounted, and because you're hitting an API, there will be something rendered to the DOM before the API call resolves itself. In my example, it'll be just be an empty div, and then it'll appear when the state updates and the render function is called again.

    You could do this more effectively by extending your state object to see whether the API response is done (you'd update this in the same place you set the content), and you could render the UI conditionally on this.

    The official docs on lifecycle methods will help you understand this pattern more.

    Good luck!