1
resposta

Ao executar ocorre o seguinte erro: TypeError: undefined is not an object (evaluating '_this3.props.foto.urlPerfil')

Não estou conseguindo importar as imagens utilizando a API Online, gera o erro acima. Aqui está o código atual do App.js:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View,AppRegistry,FlatList, Dimensions, Image} from 'react-native';

const width = Dimensions.get('screen').width;

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};
export default class App extends Component<Props> {
  constructor() {
    super();
    this.state = {
      fotos: []
    }
  }

  componentDidMount() {
    fetch('https://instalura-api.herokuapp.com/api/public/fotos/rafael')
      .then(resposta => resposta.json())
      .then(json => this.setState({fotos: json}))
  }

  render() {
    return (
      <FlatList style={styles.container}
          keyExtractor={item => item.id}
          data={this.state.fotos}
          renderItem={ ({item}) =>
              <View>
                <View style={styles.cabecalho}>
                  <Image source={{uri: this.props.foto.urlPerfil}}
                      style={styles.fotoDePerfil}/>
                  <Text>{this.props.foto.loginUsuario}</Text>
                </View>
                <Image source={{uri: this.props.foto.urlFoto}}
                    style={styles.foto}/>
              </View>

          }
      />
    );
  }
}

const styles = StyleSheet.create({
  cabecalho: {
    margin: 10,
    flexDirection: 'row',
    alignItems: 'center'
  },
  fotoDePerfil: {
    marginRight: 10,
    borderRadius: 20,
    width: 40,
    height: 40
  },
  foto: {
    width: width,
    height: width
  }
});

E também não consigo rodar a API Local pois dá erro o seguinte erro:

 ERROR 3836 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
Caused by: java.net.ConnectException: Connection refused: connect
...

Seguido de várias linhas de waning e erro (mas não cabem todas no post).

Alguém poderia me ajudar? Não estou conseguindo dar continuidade ao curso.

1 resposta

Ola Alan, tudo bem ?

Sobre rodar a API local dê uma olhada se você tem na sua máquina a infra adequada pra rodar. É necessário Java na versão 8 e o servidor de banco de dados MySQL na versão até 5.7. Deve ser esse o problema, dado que o erro nos logs mostram CommunicationsException: Communications link failure e ConnectException: Connection refused: connect mensagens típicas de quando não temos o serviço do banco de dados disponível no host.

Sobre a API rodando na nuvem, testei aqui e ela está atendendo normalmente https://instalura-api.herokuapp.com/api/public/fotos/rafael. Você pode acessar o link no navegador e ver que os dados, incluindo os links das fotos são exibidos.

Agora vamos ao problema com o código. Quando recebemos um TypeError: TypeError: undefined is not an object (evaluating '_this3.props.foto.urlPerfil'); em geral temos um problema de escrita (type) no código.

O trecho que tenta renderizar a lista tem problemas:

<FlatList style={styles.container}
          keyExtractor={item => item.id}
          data={this.state.fotos}
          renderItem={ ({item}) =>
              <View>
                <View style={styles.cabecalho}>
                  <Image source={{uri: this.props.foto.urlPerfil}}
                      style={styles.fotoDePerfil}/>
                  <Text>{this.props.foto.loginUsuario}</Text>
                </View>
                <Image source={{uri: this.props.foto.urlFoto}}
                    style={styles.foto}/>
              </View>

          }
      />

Perceba que a função que passamos para a propriedade renderItem passa um argumento (que representa cada foto da lista) que tem como nome obrigatoriamente item. Sendo assim ao tentar acessar as propriedades de cada foto, precisaremos acessar na verdade através do item.

Dessa forma:

<FlatList style={styles.container}
          keyExtractor={item => item.id}
          data={this.state.fotos}
          renderItem={ ({item}) =>
              <View>
                <View style={styles.cabecalho}>
                  <Image source={{uri: item.urlPerfil}}
                      style={styles.fotoDePerfil}/>
                  <Text>{item.loginUsuario}</Text>
                </View>
                <Image source={{uri: item.urlFoto}}
                    style={styles.foto}/>
              </View>

          }
      />

Isso deve resolver.

Você deve ter tentado acessar através de this.props.foto, porque em geral essa parte do código vai ficar separada dentro de um componente que representa cada post. Assim passaremos o item como propriedade foto pra cada post e dentro do post vamos acessar com this.props.foto. Essa parte é descrita neste exercício: https://cursos.alura.com.br/course/react-native-parte-1/task/29937

E a partir dessa divisão faremos uso dos dados que vem da api. Detalhes nesse exercício: https://cursos.alura.com.br/course/react-native-parte-1/task/29945

Espero ter ajudado. Abraço!