• EnglishEspañol日本語한국어Português
  • Inicia sesiónComenzar ahora

Te ofrecemos esta traducción automática para facilitar la lectura.

En caso de que haya discrepancias entre la versión en inglés y la versión traducida, se entiende que prevalece la versión en inglés. Visita esta página para obtener más información.

Crea una propuesta

Accede a NerdStorage desde tu Nerdlet

Sugerencia

Esta lección es parte de un curso que le muestra cómo crear una aplicación New Relic desde cero. Si aún no lo hiciste, consulta la descripción general.

Cada lección del curso se basa en la anterior, así que cerciorar de completar la última lección, Personalizar datos NRQL, antes de comenzar esta.

En lecciones anteriores, creaste una experiencia del usuario en tu aplicación que incluye gráficos y un botón para finalizar tu Prueba A/B. También configuró sus gráficos para consultar datos reales de la base de datos de New Relic. Sin embargo, dejaste datos simulados en dos gráficos:

  • Pruebas pasadas
  • Cancelaciones totales por versión

Ambos gráficos contienen datos que no se pueden obtener de New Relic. Past tests muestran información histórica de las pruebas, mientras que Total cancellations per version muestra la cantidad de cancelaciones que ve cada versión a lo largo del tiempo. Centrar, primero en Past tests.

Past tests muestran información histórica de las pruebas, por lo que debe almacenar información sobre cada prueba al finalizar. Y tiene todas las herramientas que necesita para realizar esta tarea. Primero, tiene un botón End test que activa la acción de almacenar. En segundo lugar, sabe cómo emplear NerdGraph y NerdStorage para almacenar la información de la prueba.

Almacene la información de la prueba en NerdStorage

Cambie al directorio add-nerdstorage/ab-test del repositorio de trabajos del curso:

bash
$
cd nru-programmability-course/add-nerdstorage/ab-test

Este directorio contiene el código que esperamos que tenga su aplicación en este punto del curso. Al navegar al directorio correcto al comienzo de cada lección, deja atrás su código personalizado, proteger así de llevar código incorrecto de una lección a la siguiente.

En nerdlets/ab-test-nerdlet/end-test.js, crea un método, EndTestButton.endTest():

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.closeModal}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton selectedVersion={this.state.selectedVersion}>End test</EndTestButton>
</GridItem>
</Grid>
}
}

Con este código, crea una cadena de fecha formateada, endDate. Luego, muta el almacenamiento de la cuenta con una llamada a AccountStorageMutation.mutate(). Pasa el identificador de su cuenta, el tipo de acción WRITE_DOCUMENT , &quot;pruebas pasadas&quot; como nombre de la colección, endDate como documentId y los datos del documento, que incluyen las descripciones de la versión y el ganador.

Pasas WRITE_DOCUMENT porque estás creando un documento nuevo o actualizando un documento, si ya existe uno con una colección coincidente y documentId. documentId es endDate, lo cual resulta útil para crear solo un registro por día.

Sugerencia

Si sospecha que podría completar varias pruebas en un día, deberá cambiar esta lógica.

Observe this.props.closeModal() al final del método. Esto cierra el modal que se muestra cuando intentas finalizar una prueba. Por lo tanto, puede reemplazar la devolución de llamada onClick para su botón Yes, end test en EndTestButton.render():

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.endTest}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton selectedVersion={this.state.selectedVersion}>End test</EndTestButton>
</GridItem>
</Grid>
}
}

Cuando finaliza la prueba, endTest almacena los datos de la prueba en el almacenamiento de la cuenta y cierra el modal. Este es solo la mitad del comportamiento que necesita para completar su tabla; también necesita consultar esta colección desde el almacenamiento de la cuenta.

En el archivo index.js de tu Nerdlet, pasa el ID de la cuenta y las descripciones de la versión a EndTestSection:

import React from 'react';
import { ChartGroup, Grid, GridItem } from 'nr1';
import EndTestSection from './end-test';
import NewsletterSignups from './newsletter-signups';
import PastTests from './past-tests';
import TotalCancellations from './total-cancellations';
import TotalSubscriptions from './total-subscriptions';
import VersionDescription from './description';
import VersionPageViews from './page-views';
import VersionTotals from './totals';
const ACCOUNT_ID = 123456 // <YOUR NEW RELIC ACCOUNT ID>
const VERSION_A_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter"'
const VERSION_B_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter and get a free shirt!"'
export default class AbTestNerdletNerdlet extends React.Component {
render() {
return <div>
<Grid className="wrapper">
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_A_DESCRIPTION}
version="A"
/>
</GridItem>
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_B_DESCRIPTION}
version="B"
/>
</GridItem>
<GridItem columnSpan={12}><hr /></GridItem>
<GridItem columnSpan={12}><NewsletterSignups /></GridItem>
<GridItem columnSpan={6}><TotalSubscriptions /></GridItem>
<GridItem columnSpan={6}><TotalCancellations /></GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='a' accountId={ACCOUNT_ID} />
</GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='b' accountId={ACCOUNT_ID} />
</GridItem>
<ChartGroup>
<GridItem columnSpan={6}>
<VersionPageViews version='a' />
</GridItem>
<GridItem columnSpan={6}>
<VersionPageViews version='b' />
</GridItem>
</ChartGroup>
<GridItem columnSpan={12}>
<EndTestSection
accountId={ACCOUNT_ID}
versionADescription={VERSION_A_DESCRIPTION}
versionBDescription={VERSION_B_DESCRIPTION}
/>
</GridItem>
<GridItem columnSpan={12}><PastTests /></GridItem>
</Grid>
</div>
}
}

Importante

Cerciórate de reemplazar <YOUR NEW RELIC ACCOUNT ID> con tu ID de cuenta real de New Relic.

Ahora, EndTestSection puede acceder a estas variables en sus accesorios.

Reenvíe el ID de su cuenta y las descripciones de la versión de EndTestSection a EndTestButton:

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.endTest}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton
accountIds={this.props.accountIds}
selectedVersion={this.state.selectedVersion}
versionADescription={this.props.versionADescription}
versionBDescription={this.props.versionBDescription}
>
End test
</EndTestButton>
</GridItem>
</Grid>
}
}

Obtener información de prueba de NerdStorage

En past-tests.js, actualice PastTests para recuperar datos del almacenamiento de la cuenta y mostrarlos en TableChart:

import React from 'react';
import {
AccountStorageQuery,
HeadingText,
Spinner,
TableChart,
} from 'nr1';
export default class PastTests extends React.Component {
render() {
const historicalData = {
metadata: {
id: 'past-tests',
name: 'Past tests',
columns: ['endDate', 'versionADescription', 'versionBDescription', 'winner'],
},
data: [],
}
return <div>
<HeadingText className="chartHeader">
Past tests
</HeadingText>
<AccountStorageQuery accountIds={this.props.accountIds} collection="past-tests">
{({ loading, error, data }) => {
if (loading) {
return <Spinner />;
}
if (error) {
console.debug(error);
return 'There was an error fetching your data.';
}
data.forEach(
function (currentValue, index) {
historicalData.data.push({
endDate: currentValue.id,
versionADescription: currentValue.document.versionADescription,
versionBDescription: currentValue.document.versionBDescription,
winner: currentValue.document.winner,
})
}, data
)
return <TableChart data={[historicalData]} fullWidth />
}}
</AccountStorageQuery>
</div>
}
}

Primero, eliminaste los datos simulados de historicalData. Luego, usaste AccountStorageQuery para recuperar datos de NerdStorage. Pasó su identificador de cuenta y el nombre de la colección en la que almacenó el documento.

Observe que hay tres valores de retorno de la consulta:

  • loading
  • error
  • data

Si la consulta está en curso, loading es true. En este caso, muestra un componente Spinner de interfaz de usuario para informarle que la tabla aún no está lista. Si la consulta arrojó un error, puede ver información sobre ese error en la variable error. Log esa información en la consola con fines de depuración y devuelve un mensaje de error. Si la consulta se devolvió correctamente, puede acceder a los datos de la variable data. Debido a que los datos no coinciden con el formato que requiere TableChart , recorre los datos y los formatea de acuerdo con las especificaciones TableChart. Finalmente, pasas historicalData a tu TableChart.

En el archivo index.js de tu Nerdlet, pasa tu ACCOUNT_ID a PastTests:

import React from 'react';
import { ChartGroup, Grid, GridItem } from 'nr1';
import EndTestSection from './end-test';
import NewsletterSignups from './newsletter-signups';
import PastTests from './past-tests';
import TotalCancellations from './total-cancellations';
import TotalSubscriptions from './total-subscriptions';
import VersionDescription from './description';
import VersionPageViews from './page-views';
import VersionTotals from './totals';
const ACCOUNT_ID = 1234567 // <YOUR NEW RELIC ACCOUNT ID>
const VERSION_A_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter"'
const VERSION_B_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter and get a free shirt!"'
export default class AbTestNerdletNerdlet extends React.Component {
render() {
return <div>
<Grid className="wrapper">
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_A_DESCRIPTION}
version="A"
/>
</GridItem>
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_B_DESCRIPTION}
version="B"
/>
</GridItem>
<GridItem columnSpan={12}><hr /></GridItem>
<GridItem columnSpan={12}><NewsletterSignups /></GridItem>
<GridItem columnSpan={6}><TotalSubscriptions /></GridItem>
<GridItem columnSpan={6}><TotalCancellations /></GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='a' accountId={ACCOUNT_ID} />
</GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='b' accountId={ACCOUNT_ID} />
</GridItem>
<ChartGroup>
<GridItem columnSpan={6}>
<VersionPageViews version='a' />
</GridItem>
<GridItem columnSpan={6}>
<VersionPageViews version='b' />
</GridItem>
</ChartGroup>
<GridItem columnSpan={12}>
<EndTestSection
accountId={ACCOUNT_ID}
versionADescription={VERSION_A_DESCRIPTION}
versionBDescription={VERSION_B_DESCRIPTION}
/>
</GridItem>
<GridItem columnSpan={12}>
<PastTests accountId={ACCOUNT_ID} />
</GridItem>
</Grid>
</div>
}
}

Importante

Cerciórate de reemplazar <YOUR NEW RELIC ACCOUNT ID> con tu ID de cuenta real de New Relic.

Navega hasta la raíz de tu Nerdpack en nru-programmability-course/add-nerdstorage/ab-test.

Genera un nuevo UUID para tu Nerdpack:

bash
$
nr1 nerdpack:uuid -gf

Debido a que clonaste el repositorio de trabajos del curso que contenía un Nerdpack existente, necesitas generar tu propio identificador único. Este UUID asigna su Nerdpack a su cuenta New Relic. También permite que su aplicación realice solicitudes de Nerdgraph en nombre de su cuenta.

Entregue su aplicación localmente:

bash
$
nr1 nerdpack:serve

Vaya a https://one.newrelic.com?nerdpacks=local y vea su aplicación en Apps > Your apps.

Al principio, no deberías ver ningún dato.

Haga clic en End test y apruebe su acción en el modal. Ahora verás datos en Past tests.

Sugerencia

Si algo no funciona, emplee las herramientas de depuración de su browser para intentar identificar el problema.

Cerciorar:

  • Copié el código correctamente de la lección.
  • Generó un nuevo UUID
  • Reemplazó todas las instancias de <YOUR NEW RELIC ACCOUNT ID> en su proyecto con su New Relic ID de cuenta real

Cuando terminó, deje de servir su aplicación New Relic presionando CTRL+C en la ventana de terminal de su servidor local.

¡Buen trabajo! Ahora tiene experiencia en el uso de los componentes de mutación y consulta de NerdStorage. Sin embargo, todavía hay un gráfico más con datos simulados: Total cancellations per version.

Total cancellations per version es diferente al resto de gráficos de tu aplicación Prueba A/B. Debido a que New Relic no sabe cuántos usuarios se dan de baja de su boletín, debe aplicar esa información a una fuente externa. Para los fines de este curso, creamos un servicio de datos externo que proporciona datos de cancelación de boletines falsos para que usted los consuma en su aplicación. Este servicio simulado se encuentra en https://api.nerdsletter.net/cancellations.

La aplicación New Relic es una aplicación React, lo que significa que puede usar las funciones de React y Javascript para recopilar datos no solo de New Relic, sino también de cualquier servicio externo. En una lección posterior, aprenderá cómo buscar más allá de New Relic datos que le informarán sobre cómo su software le está ayudando a alcanzar sus objetivos comerciales. Pero antes de aprender eso, necesita saber algo sobre nuestro servicio de datos simulados: ¡requiere un encabezado de Autorización!

En esta lección, aprendiste cómo usar NerdStorage para consultar y mutar datos en el almacén de datos de tu propia aplicación. Si bien NerdStorage es un excelente lugar para muchas categorías de datos, no es apropiado para datos confidenciales, como un token que pasarías en un encabezado de Autorización a un servicio externo. Para eso, usarías NerdStorageVault.

Sugerencia

Esta lección es parte de un curso que le muestra cómo crear una aplicación New Relic desde cero. Continúe con la siguiente lección: acceda a NerdStorageVault desde su nerdlet.

Copyright © 2024 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.