How to convert the response to an Axios request with React-Native?

Asked

Viewed 2,105 times

1

I have this class that works perfectly:

import React, {Component} from 'react';

import Icon from 'react-native-vector-icons/FontAwesome';
import AsyncStorage from '@react-native-community/async-storage';
import {View, Text} from 'react-native';

import api from '../../services/api';
import styles from './styles';
import Header from '../../components/Header';

export default class Perfil extends Component {
  state = {
    data: [],
  };

  async componentDidMount() {
    console.tron.log('DID MOUNT');
    const username = await AsyncStorage.getItem('@Loger:email');
    this.loadRepositories(username);
    console.tron.log('USERNAME' + username);
  }
  loadRepositories = async username => {
    const {data} = await api.get(`/usuarios/email/${username}`);
    console.tron.log(data);
    this.setState({data});
  };

  render() {
    return (
      <View style={styles.container}>
        <Header title="Profile" />
        {this.state.data.map(texto => (
          <View>           
              <Text style={styles.infoNome}>{texto.nome}</Text>
              <Text style={styles.infoText}>{texto.nascimento}</Text>                
              <Text style={styles.infoText}>{texto.email}</Text>
             <Text style={styles.infoText}>{texto.telefone}</Text>             
             <Text style={styles.infoText}>{texto.endereco}</Text>            
          </View>
        ))}
      </View>
    );
  }
}

Now this second screen makes the same request and does not render anything on the screen:

import React, {Component} from 'react';
import Icon from 'react-native-vector-icons/FontAwesome';
import AsyncStorage from '@react-native-community/async-storage';
import {View, Text} from 'react-native';

import api from '../../services/api';
import styles from './styles';
import Header from '../../components/Header';

export default class Perfil extends Component {
  state = {
    nome: '',
    nascimento: '',
    email: '',
    telefone: '',
    endereco: '',
  };

  async componentDidMount() {
    console.tron.log('DID MOUNT');
    const username = await AsyncStorage.getItem('@Loger:email');
    this.loadRepositories(username);
    console.tron.log('USERNAME' + username);
  }
  loadRepositories = async username => {
    const {data} = await api.get(`/usuarios/email/${username}`);
    console.tron.log('DATA: ' + this.state);
    const {nome, nascimento, email, telefone, endereco} = data;
    this.setState({nome, nascimento, email, telefone, endereco});
  };

  render() {
    const {nome, nascimento, email, telefone, endereco} = this.state;
    return (
      <View style={styles.container}>
        <Header title="Profile" />

        <View>
          <View style={styles.info}>
            <Text style={styles.infoNome}>{nome}</Text>
            <Text style={styles.infoText}>{nascimento}</Text>
            <Text style={styles.infoText}>{email}</Text>
            <Text style={styles.infoText}>{telefone}</Text>
            <Text style={styles.infoText}>{endereco}</Text>
          </View>
        </View>
      </View>
    );
  }
}

I don’t think I’m doing the de-structuring properly... How to make the second screen work ?

I don’t want to use that piece of code this.state.data.map to do the mapping as in the first class.

This is the return of the request made on Insomnia:

[
  {
    "_id": "5d9ba2de73f4f77f2fcb1610",
    "nome": "Kiko",
    "nascimento": "10/10/2000",
    "email": "[email protected]",
    "telefone": "356-7890",
    "endereco": "Rua Maria da Silva Esperança",
    "__v": 0
  }
]

Exit in debug:

inserir a descrição da imagem aqui

How to change this backend code(Node , express, Mongo, mongose) to return an object and not an array when I pass the email parameter:

controller:

const mongoose = require("mongoose");

const Usuario = mongoose.model("Usuario");

module.exports = {
  async index(req, res) {
    const { page = 1 } = req.query;
    // const usuarios = await user.paginate({}, { page, limit: 10 });
    const usuarios = await Usuario.find();
    return res.json(usuarios);
  },
  async show(req, res) {
    const user = await Usuario.findById(req.params.id);
    return res.json(user);
  },

  async find(req, res) {
    try {
      const user = await Usuario.find({ email: req.params.email });
      if (user.length === 0) {
        return res.status(400).send({ error: "Error loading  contact" });
      }
      return res.json(user);
    } catch (error) {
      return res.status(400).send({ error: "Error loading  contact" });
    }
  },

  async update(req, res) {
    const user = await Usuario.findByIdAndUpdate(req.params.id, req.body, {
      new: true
    });

    return res.json(user);
  },
  async store(req, res) {
    const user = await Usuario.create(req.body);

    return res.json(user);
  },
  async destroy(req, res) {
    await Usuario.findByIdAndRemove(req.params.id);

    return res.send();
  }
};

Model:

const mongoose = require("mongoose");
const mongoosePaginate = require("mongoose-paginate-v2");

const UsuarioSchema = new mongoose.Schema({
  nome: {
    type: String,
    required: true
  },
  nascimento: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  telefone: {
    type: String,
    required: true
  },
  endereco: {
    type: String,
    required: true
  }
});
UsuarioSchema.plugin(mongoosePaginate);

mongoose.model("Usuario", UsuarioSchema);
  • 1

    Could you show the return of Axios? Specifically what comes within the date?

  • @Felipeavelar That and return DATA: [Object Object]

  • 1

    From what I’m seeing, data is an array type. If you want to take only the first element, try to change in loadRepositories for const {nome, nascimento, email, telefone, endereco} = data[0];. However, if you have access to the backend, it would be interesting to return only the user you want.

  • @Felipeavelar It worked man! Thank you very much. The worst is that I had ever tried something like.

1 answer

3


As discussed in the comments, the problem is that data is a vector returned from the server, so unstructuring won’t work if you don’t tell which vector index you want to unstructure. To fix the problem just change the line:

const {nome, nascimento, email, telefone, endereco} = data;

for:

const {nome, nascimento, email, telefone, endereco} = data[0];

If you want the first element of the vector. However, some observations are important.

  1. If you have access to the application backend, it is interesting that you create a route that returns a single user, so you do not need to access the first element of the vector;
  2. If you cannot change the route, you need to check if there is any element in the vector, otherwise make the necessary treatments so that your application does not stop working.

EDITION

How you’re using the moongose, from what I understand from your controller, the route index must return a list, while the route find returns only one user, whereas email should be a single user key. In this case, just replace:

await Usuario.find({ email: req.params.email });

for:

await Usuario.findOne({ email: req.params.email });

However, it is important to note that the findOne return the first element found, if there is more than one and, if there is none, return null. Therefore, it is important to make sure that the field being searched is unique, otherwise there may be unwanted results.

  • @Felpeavelar Thanks man, I accepted the answer and still gave a positive vote for her :) but I can’t do it right? const {name, birth, email, phone, address} = await api.get( /usuarios/email/${username}, ); this.setState({name, birth, email, phone, address}); I tried but it did not load anything on the screen. If you found the interesting question of an up in her ai brother...

  • No, because the object he is returning is a Sponse, must give if you put one. date at the end of your.get api, but crowding too much code into one line only makes it unreadable, the idea would be to destroy the Answer at a constant date and then unstructure that constant, since it would be clearer to another developer who is taking your code (:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.