Как я могу получить данные из массива объектов, передать их через конечную точку API в .fetch () нужное значение объекта с помощью React? - PullRequest
0 голосов
/ 20 марта 2020

Я создаю панель мониторинга отчетов с помощью PowerBI с использованием React, и мне нужно передать значение токена встраивания в конечную точку бэкенда, которую мы создали, чтобы затем передать это новое значение в компонент встраивания PowerBI для правильного отображения отчета.

Приложение работает, если я вручную помещаю значения токена для встраивания, но это не идеально по нескольким причинам (например, из-за безопасности и времени), поэтому я пытаюсь автоматизировать это в приложении React.

Как мы отображаем отчеты вручную, с помощью оператора switch, так как есть несколько отчетов на выбор, и в каждом из них размещен компонент PowerbiEmbedded с соответствующими значениями, извлекаемыми из локального файла JSON, где идентификаторы отчетов и URL-адреса для встраивания помещены. Это тот же файл, который я вставил в токены для тестирования / проверки концепции, и у меня есть отдельный компонент, обрабатывающий запрос на выборку (RequestToken. js ниже), и он немного потерян при подключении этого к ReportDashboard. js, поскольку это что обрабатывает отображение каждого отчета.

Буду очень признателен за любые предложения и помощь в этом!


RequestToken. js

import React from "react"
import { groupVariables } from '../constants/reportVariables';


// This will handle token retrieval for each 
class RequestAccessToken extends React.Component {

    state = {
        isLading: true,
        tokenDetails: [],
        error: null
    };

    getTokenDetails() {

        // where we're fetching data from b2b for proof of concept
        axios.get(`/api/token/${accessToken}`)

        // got the API response and receive data in JSON format
        .then(response => 
            response.data.results.map(tokenDetail => ({
                token: `${tokenDetail.token}`
            }))
        )

        .then(tokenDetails => {
            this.setState({
                tokenDetails,
                isLoading: false
            });
        })

        // catch any errors we hit and update the output
        .catch(error => this.setState({ error, isLoading: false }));
    }

    componentDidMount() {
        this.getTokenDetails();
    }

    render() {
        const { isLoading, tokenDetails } = this.state;
        return (
            <React.Fragment>
                {!isLoading ? (
                    tokenDetails.map(tokenDetail => {
                        const { token } = tokenDetail
                        return (
                            console.log(tokenDetail)
                        );
                    })
                // If there is a delay in data, let's let the user know it's loading
                ) : (
                <h3>Loading...</h3>
                )}
            </React.Fragment>
        );
    }
}

ReportDashboard. js

import React from 'react';
import { reportVariables } from '../constants/reportVariables.js';
import PowerbiEmbedded from 'react-powerbi'

function Reporting({ activeView }) {
  // configure the reportIds and report name in constants/reportVariables.js
  let reportData;

  switch(activeView){
    case 'Business to Consumer':
      reportData = <div>
        <PowerbiEmbedded
          id={reportVariables.reportIds.b2c}
          embedUrl={reportVariables.reportURL.b2c}
          accessToken={reportVariables.reportToken.b2c}
          filterPaneEnabled={false}
          navContentPaneEnabled={false}
          embedType={`report`}
          tokenType={`Embed`}
          permissions={`All`}
        />
      </div>
      break;
    case 'Business to Business': 
      reportData = <div>
      <PowerbiEmbedded
          id={reportVariables.reportIds.b2b}
          embedUrl={reportVariables.reportURL.b2b}
          accessToken={reportVariables.reportToken.b2b}
          filterPaneEnabled={false}
          navContentPaneEnabled={false}
          embedType={`report`}
          tokenType={`embed`}
          permissions={`All`}
        />
    </div>
      break;
    case 'Agent':
      reportData = <div>
      <PowerbiEmbedded
          id={reportVariables.reportIds.agent}
          embedUrl={reportVariables.reportURL.agent}
          accessToken={reportVariables.reportToken.agent}
          filterPaneEnabled={false}
          navContentPaneEnabled={false}
          embedType={`report`}
          tokenType={`embed`}
          permissions={`All`}
        />
    </div>
      break;
    case 'A/B Testing':
      reportData = <div>
        <iframe width="560" height="315" src="https://www.youtube.com/embed/lcGoWfXLRpc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
      </div>
      break;
    default: 
      break;
  }

  return(
    <div className='frameDiv'>  
      <style>{`
        .frameDiv{
          justify-content: center;
          display: flex;
          align-items: center;
          width: 85vw;
          height: calc(100vh - 39px);
          background: #ccc;
        }
        .powerbi-frame {
          width: 85vw;
          height: calc(100vh - 39px);
        }
        `}
      </style>

        {reportData}

    </div>
  ); 
}
export default Reporting

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Есть много способов передать токен другим компонентам, но все сводится к тому, чтобы «передать его как опору». Вы можете использовать контекст React, централизованное управление состоянием или родительское / дочернее вложение. Другой вариант, который, я думаю, был бы наиболее элегантным, состоял бы в создании компонента более высокого порядка (HO C), который обертывает любой компонент с помощью компонента RequestAccessToken:

import { useEffect, useState } from 'React';

function withAccessToken(accessToken) {
  return Component => props => {
    const [state, setState] = useState({
      isLoading: true,
      tokenDetails: [],
      error: null
    });

    useEffect(() => {
      axios.get(`/api/token/${accessToken}`)
        // where we're fetching data from b2b for proof of concept

        // got the API response and receive data in JSON format
        .then(response => 
            response.data.results.map(tokenDetail => ({
                token: `${tokenDetail.token}`
            }))
        )

        .then(tokenDetails => {
            setState({
              tokenDetails,
              isLoading: false
            });
        })

        // catch any errors we hit and update the output
        .catch(error => setState({ error, isLoading: false }));
    }, []);

    const { isLoading, tokenDetails, error } = state;
    return (
      isLoading && <h3>Loading...</h3>
      || error && <h3>Error loading token</h3>
      || <Component {...props} accessToken={tokenDetails}/>
    );
  };
}

Способ, которым вы использование этого было бы что-то вроде:

const B2BReport = withAccessToken('some-token-name')(({ accessToken }) =>
  <PowerbiEmbedded
    id={reportVariables.reportIds.b2b}
    embedUrl={reportVariables.reportURL.b2b}
    accessToken={accessToken}
    filterPaneEnabled={false}
    navContentPaneEnabled={false}
    embedType={`report`}
    tokenType={`embed`}
    permissions={`All`}
  />
);

Это создает новый B2BReport компонент, который получает accessToken проп, введенный HO C. Затем вы должны отобразить этот <B2BReport/> компонент в вашем ReportDashboard компоненте.

0 голосов
/ 20 марта 2020

RequestAccessToken должен быть обработан где-то верно? На данный момент он просто сидит там. Импортируйте его в свой компонент Dashboard и выполните рендеринг, после чего вы сможете получить доступ к своему токену там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...