如何使用axios和javascript为单个元素传递url的id值

问题描述 投票:1回答:3

我正在使用swapi(https://swapi.co/),AXIOS和VUE显示角色的数据参数(名称,高度,质量......)。

我已经有了一个字符的url(即http://localhost:8081/person/1),我希望它与swapi API(https://swapi.co/api/people/1/)匹配,但我不知道我的错误在哪里

我正在使用Axios和Vue,我已经为Axios get请求和在我的vue文件中获取信息的方法提供了服务。

我的“people.service.js”服务的代码是这样的:

import axios from "axios";

const PeopleService = {};

// PeoplesService.getPeoples = async () => {}; - Para sacar el listado de planetas con un v-for

PeopleService.getPeople = async id => {
  try {
    const result = await axios.get(`people/${id}`);

    // For getting the species

    const specieRoute = result.data.species[0].split("/");
    const idSpecie = specieRoute[specieRoute.length - 2];
    const especie = await axios.get(`species/${idSpecie}`);

    // For getting the planets

    const planetRoute = result.data.homeworld.split("/");
    const idPlanet = planetRoute[planetRoute.length - 2];
    const planeta = await axios.get(`planets/${idPlanet}`);

    // console logs to show results

    console.log(result.data);
    console.log(idSpecie);
    console.log(especie.data);
    console.log(planeta.data);

    // data information

    const people = {
      nombre: result.data.name,
      altura: result.data.height,
      peso: result.data.mass,
      genero: result.data.gender,
      piel: result.data.skin_color,
      especie: especie.data.name, // Lo saco del servicio de especies
      planeta: planeta.data.name // Lo saco del servicio de planetas
    };

    return people;
  } catch (error) {
    const errorStatus = error.response.status;
    let errorMessage = "";

    if (errorStatus === 404) {
      errorMessage = "No se encontró al personaje";
    } else {
      errorMessage = "Ocurrió un error";
    }

    throw new Error(errorMessage);
  }
};

export default PeopleService;

我的vue文件是:

<template>
  <div>

    The id is {{ $route.params.id }}, and the name is {{ people.nombre }}

  </div>
</template>

<script>
import PeopleService from "@/services/people.service";

export default {
  async create() {
    this.userId = this.$route.params.id;
    this.getUser();
  },

  data() {
    return {
      user: null,
      loading: false,
      error: null,
      userId: this.$route.params.id
    };
  },
  methods: {
    async getUser() {
      try {
        this.loading = true;
        this.people = null;
        this.error = null;
        this.people = await PeopleService.getPeople(this.userId);
      } catch (error) {
        this.error = error.message;
      } finally {
        this.userId = null;
        this.loading = false;
      }
    }
  }
};
</script>

<style lang="scss" scoped></style>

我希望结果是角色的名字,但我得到"[Vue warn]: Error in render: "TypeError: Cannot read property 'nombre' of undefined"

javascript vue.js axios
3个回答
0
投票

我正在创建第二个答案,以便概述如何使用vue-router执行此操作,因为您询问它。

免责声明:这不是“最干净”的代码 - 这个伪代码旨在松散地说明您的目标。

希望这可以帮助!


CodePen mirror


const PeopleService = {};
PeopleService.getPeople = async id => {
  try {
    const result = await axios.get(`https://swapi.co/api/people/${id}`);
    const specieRoute = result.data.species[0].split("/");
    const idSpecie = specieRoute[specieRoute.length - 2];
    const especie = await axios.get(`https://swapi.co/api/species/${idSpecie}`);
    const planetRoute = result.data.homeworld.split("/");
    const idPlanet = planetRoute[planetRoute.length - 2];
    const planeta = await axios.get(`https://swapi.co/api/planets/${idPlanet}`);
    const people = {
      nombre: result.data.name,
      altura: result.data.height,
      peso: result.data.mass,
      genero: result.data.gender,
      piel: result.data.skin_color,
      especie: especie.data.name, // Lo saco del servicio de especies
      planeta: planeta.data.name // Lo saco del servicio de planetas
    };
    return people;
  } catch (error) {
    const errorStatus = error.response.status;
    let errorMessage = "";
    if (errorStatus === 404) {
      errorMessage = "No se encontró al personaje";
    } else {
      errorMessage = "Ocurrió un error";
    }
    throw new Error(errorMessage);
  }
};

const peopleComponent = {
  name: 'people',
  template: "#peopleComponent",
  data() {
    return {
      userId: null,
      peopleArray: [],
      peopleObject: null,
      error: null
    };
  },
  mounted() {
    this.userId = this.$route.params.id;
    this.getUser();
  },
  methods: {
    async getUser() {
      try {
        let person = await PeopleService.getPeople(this.userId);
        this.peopleArray.push(person); // add to array
        this.peopleObject = person; // assign to object
      } catch (error) {
        this.error = error.message;
      }
    }
  }
};

const homeComponent = {
  name: 'home',
  template: "#homeComponent",
}

const routes = [
    { path: '', name: 'home', component: homeComponent },
    { path: '/people/:id', name: 'people', component: peopleComponent },
]

const router = new VueRouter({ routes });

new Vue({
    router
}).$mount('#app');
.nav-links {
  background-color: lightgray;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.4/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

<div id="app">
  <div>
    <router-view></router-view>
  </div>
</div>

<script type="text/x-template" id="homeComponent">
  <div>
    <hr/>
    <div class="nav-links">
      <h2>Home</h2>
      <div>
        <router-link :to="{ name: 'people', params: { id: 1 } }">Person 1</router-link>
        <br/>
        <router-link :to="{ name: 'people', params: { id: 2 } }">Person 2</router-link>
      </div>
    </div>
    <hr/><br/>
  </div>
</script>

<script type="text/x-template" id="peopleComponent">
  <div>
    <hr/>
    <div class="nav-links">
      <h2>People</h2>
      <div>
        <router-link :to="{ name: 'home' }">Home</router-link>
      </div>
    </div>
    <hr/><br/>
    <h3>People as ARRAY</h3>
    <div v-if="peopleArray.length > 0">
      <div v-for="(p, index) in peopleArray" :key="index">
        <div><b>nombre:</b> {{ p.nombre }}</div>
        <div><b>altura:</b> {{ p.altura }}</div>
        <div><b>peso:</b> {{ p.peso }}</div>
        <div><b>genero:</b> {{ p.genero }}</div>
        <div><b>piel:</b> {{ p.piel }}</div>
        <div><b>especie:</b> {{ p.especie }}</div>
        <div><b>planeta:</b> {{ p.planeta }}</div>
      </div>
    </div>
    <div v-else>
      <i>Loading People...</i>
    </div>
    <br/>
    <hr/> --- OR ---
    <hr/><br/>
    <h3>People as OBJECT</h3>
    <div v-if="peopleObject != null">
      <div v-for="(p, index) in peopleObject" :key="index">
        {{ p }}
      </div>
    </div>
    <div v-else>
      <i>Loading People...</i>
    </div>
  </div>
</script>

0
投票

编辑:在为其分配值之前,您似乎没有设置data.people属性。您可以尝试在数据下添加people属性并重试吗?

...
data() {
  return {
    ...
    people: null,
    ...
  }
}
...

首先,目前还不是很清楚你是如何向swapi发送请求的......你是怎么做到的?

我用你的代码编写了你想要完成的修改版本,但是使用swapi URL ...如果你改变代码使用swapi URL而不是localhost,它是否有效?


CodePen mirror

代码段也可在下面找到

编辑:CodePen with routing example - 详细的二级答案也已发布..


如果您在本地代理请求

您的服务器端配置是什么样的?你使用node或其他什么?你是如何实际向swapi发送API请求的?


如果您使用的是本地数据库

您的本地数据库中是否包含任何数据?在尝试查询本地数据库中的数据之前,您可能需要设置一个从swapi API中提取数据并将其保存到本地数据库的服务。


我也没有使用任何路由,因此您的路由可能存在问题?无论如何,我希望这会有所帮助:

/**
 * People service
 */
const PeopleService = {};
PeopleService.getPeople = async id => {
  try {
    const result = await axios.get(`https://swapi.co/api/people/${id}`);
    const specieRoute = result.data.species[0].split("/");
    const idSpecie = specieRoute[specieRoute.length - 2];
    const especie = await axios.get(`https://swapi.co/api/species/${idSpecie}`);
    const planetRoute = result.data.homeworld.split("/");
    const idPlanet = planetRoute[planetRoute.length - 2];
    const planeta = await axios.get(`https://swapi.co/api/planets/${idPlanet}`);
    const people = {
      nombre: result.data.name,
      altura: result.data.height,
      peso: result.data.mass,
      genero: result.data.gender,
      piel: result.data.skin_color,
      especie: especie.data.name,
      planeta: planeta.data.name
    };
    return people;
  } catch (error) {
    const errorStatus = error.response.status;
    let errorMessage = "";
    if (errorStatus === 404) {
      errorMessage = "No se encontró al personaje";
    } else {
      errorMessage = "Ocurrió un error";
    }
    throw new Error(errorMessage);
  }
};

/** 
 * Vue app
 */
new Vue({
  el: "#app",
  data: {
    userId: 1,
    peopleArray: [],
    peopleObject: null,
    error: null
  },
  mounted() {
    this.getUser();
  },
  methods: {
    async getUser() {
      try {
        let person = await PeopleService.getPeople(this.userId);
        this.peopleArray.push(person); // add to array
        this.peopleObject = person; // assign to object
      } catch (error) {
        this.error = error.message;
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

<div id="app">
  <h3>People as ARRAY</h3>
  <div v-if="peopleArray.length > 0">
    <div v-for="(p, index) in peopleArray" :key="index">
      <div><b>nombre:</b> {{ p.nombre }}</div>
      <div><b>altura:</b> {{ p.altura }}</div>
      <div><b>peso:</b> {{ p.peso }}</div>
      <div><b>genero:</b> {{ p.genero }}</div>
      <div><b>piel:</b> {{ p.piel }}</div>
      <div><b>especie:</b> {{ p.especie }}</div>
      <div><b>planeta:</b> {{ p.planeta }}</div>
    </div>
  </div>
  <div v-else>
    <i>Loading People...</i>
  </div>
  <br/><hr/> --- OR --- <hr/><br/>
  <h3>People as OBJECT</h3>
  <div v-if="peopleObject != null">
    <div v-for="(p, index) in peopleObject" :key="index">
      {{ p }}
    </div>
  </div>
  <div v-else>
    <i>Loading People...</i>
  </div>
</div>

0
投票

vue文件的正确代码是:

<template>
<div>
  <h3>Modo array</h3>
  <div v-if="peopleArray.length > 0"> // Detecta que el id es mayor que 0
    <div v-for="(p, index) in peopleArray" :key="index">
      <div><b>nombre:</b> {{ p.nombre }}</div>
      <div><b>altura:</b> {{ p.altura }}</div>
      <div><b>peso:</b> {{ p.peso }}</div>
      <div><b>genero:</b> {{ p.genero }}</div>
      <div><b>piel:</b> {{ p.piel }}</div>
      <div><b>especie:</b> {{ p.especie }}</div>
      <div><b>planeta:</b> {{ p.planeta }}</div>
    </div>
  </div>
  <div v-else>
    <i>Loading People...</i>
  </div>
  <br/><hr/> --- <hr/><br/>
  <h3>Modo objeto</h3>
  <div v-if="peopleObject != null">
    <div v-for="(p, index) in peopleObject" :key="index">
      {{ p }}
    </div>
  </div>
  <div v-else>
    <i>Loading People...</i>
  </div>
  </div>
</template>

<script>
import PeopleService from "@/services/people.service";

export default {

  data() {
    return {
      userId: null,
      loading: false,
      peopleArray: [], // Para obtener los valores como array
      peopleObject: null, // Para que los valores que devuelva sean como array o como objeto
      error: null
    };
  },
  mounted() {
    this.userId = this.$route.params.id; // el userId corresponde con el último número de la url
    this.getUser();  
    },
  methods: {
    async getUser() {
      try {
        this.loading = true;
        this.people = null;
        this.error = null;
        let person = await PeopleService.getPeople(this.userId); // Hace la petición sobre el userID
        this.peopleArray.push(person); // Añadir al array
        this.peopleObject = person; // Asignar a objeto
      } catch (error) {
        this.error = error.message;
      } finally {
        this.userId = null;
        this.loading = false;
      }
    }
  }
};
</script>

<style lang="scss" scoped></style>
© www.soinside.com 2019 - 2024. All rights reserved.