so my api is returning the correct info from my sqlite db ( i think)
this is the response i get when i just do {{ vendor }}
[ { "id": 1, "vendor_name": "pip" }, { "id": 3, "vendor_name": "test1" } ]
but when i add the ".vendor_name" to the v-for in my template it disappears
is the api response in the wrong format or am i assigning it to the "ref" wrong?
im new to vue and im trying to figure out why this is happening
any help is greatly appreciated
<script >
import axios from 'axios'
import { ref } from 'vue'
export default {
setup () {
const vendors = ref()
const loadvendors = async () => {
const response = await axios.get('http://localhost:1337/vendors')
vendors.value = response.data
}
loadvendors()
return {
vendors
}
}
}
</script>
<template>
<h1>Vendors</h1>
<li v-for="vendor in vendors">{{ vendor.vendor_name }}</li>
</template>
I think. You should load data from api onMounted() and you should set any value in ref([]) or ref(null);
got it, all i had to do was use
<li v-for="vendor in vendors.vendors" :key="vendors.id">{{ vendor.vendor_name }}</li>
instead of
<li v-for="vendor in vendors" :key="vendors.id">{{ vendor.vendor_name }}</li>
Related
I have a simple api returning a json object that I want to display unto the screen.
However when I display the $data property I'm getting html and not the json from the api.
However whenever I refresh the page with f5 or manually the data then shows up on the screen and not the html.
{
"data": {
"positions": 2,
"departments": 2,
"paygrades": 8
}
}
<template>
<v-container>
<v-row> {{ $data.dbData }}</v-row>
</v-container>
</template>
<script>
export default {
async asyncData({ $axios }) {
const dbData = await $axios.$get('/dashboard')
return dbData
},
data() {
return {
}
},
}
</script>
Edited code
<template>
<v-container>
<v-row> {{ dbData }}</v-row>
</v-container>
</template>
<script>
export default {
data() {
return {
dbData: null,
}
},
async fetch() {
this.dbData = await this.$axios.$get('/dashboard')
},
}
</script>
My goal is to map an array within a json object I'm calling from my API call with axios and fetchContext I had written for passing headers.
My problem, I can console.log the data but whenever I try to return the results array I get no list items.
My json from the console.log to get the results array:
{count: 4, results: Array(4)}
count: 4
results: (4) [{…}, {…}, {…}, {…}]
My ReactJS Component:
import React, { useState, useContext, useEffect } from 'react';
import { FetchContext } from '../context/FetchContext';
export const RandomPage = () => {
const fetchContext = useContext(FetchContext);
const [bookData, setBookData] = useState([]);
useEffect(() => {
const getData = async () => {
try {
const { data } = await fetchContext.authAxios.get('/dummylibrary/book/');
setBookData(data.bookData);
console.log(data);
} catch (err) {
console.log(err);
}
};
getData();
}, [fetchContext.authAxios]);
return (
<>
<ul>
{bookData &&
bookData.map((book) => (
<li key={book.id}>
{book.id}
</li>
))}
</ul>
</>
);
};
What did I miss or am not calling correctly in my React Component? My apologies in advance if this is a repeat, the answers out there didn't quite match up.
I was missing data.results in my setBookData. Thank you #Naren and #Drew Reese.
I am making a vue app. I put a .json file in static directory. I am trying to read it in the default HelloWorld.vue file. But it's not showing in the browser. Here is what it shows in the browser:
My json file looks like this:
{
"status": "success",
"message": "Successfully retrieved all registered applications",
"Applications": [
{
"ApplicationID": "74382DOD",
"ApplicationName": "OIMInstance2",
"ApplicationType": "OIM",
"APIToken": "ZM8R4FRiZWWKbl235u06zbArCdOBPlEKhqHQO8Y9RJ2HgBPC+cZgbIli8fFuNZaey/2tJciJuILIWIn24WTjGA=="
},
{
"ApplicationID": "943ODA6G",
"ApplicationName": "LDAPInstance2",
"ApplicationType": "LDAP",
"APIToken": "R9lDEW5dnN6TZg2sefEEzS6LWMNmFh4iLHMu47LmAsusHl0bZuh2rktSlXqSZRdHHEWq7sP4Xsdy6xNtDYE8xw=="
}
]
}
My code in HelloWorld.vue is:
<template>
<div>
<h1>APPLICATION REGISTRATION</h1>
<div v-for="udata in userData">
Id : {{ udata.ApplicationID }}
</div>
</div>
</template>
<script>
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
export default {
name: 'HelloWorld',
data () {
return {
userData: []
}
},
created: function() {
axios.get('../../static/mockdata.json')
.then(response => {
this.userData = response.data
})
.catch(e => {
//this.errors.push(e)
})
}
}
</script>
Is there anything wrong with my code? How do I show the json data in the browser?
You need to iterate through applications object.Hence in order to get applicationId you will need to set data accordingly by only adding applications data in your userData variable.
Do as below.
this.userData = response.data.Applications
I have a json file named autofill.json and it's created to autofill a search bar when pressed on.
the autofill.json is a test file that's why it looks like this.
[
{
"a": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
}
},
"b": {
"box": {
"name": "apple",
"href": "https://www.berserk.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
]
The .json file is then fetched in the file named FetchAndParseResults.js
import fetch from 'isomorphic-fetch'
const FetchAndParseResults = (url) => {
return fetch(url).then(response => {
const parsedJson = response.json()
return parsedJson
})
}
export default FetchAndParseResults
The data that gets fetched is used in searchcontainer.js where everything gets placed in, the search etc.
import React from 'react'
import Searchbar from './index.js'
import FetchAndParseResults from './FetchAndParseResults.js'
class SearchContainer extends React.Component {
state = {
results: []
}
performSearch = event => {
return FetchAndParseResults('static/autofill.json').then(data => {
this.setState({ results: data })
})
}
render () {
console.log('performSearch event', this.performSearch)
console.log('data inside performSearch', this.state.results)
return (
<Searchbar
performSearch={this.performSearch}
results={this.state.results}
/>
)
}
}
export default SearchContainer
Then to map through the data that is in autofill.json there is a file named autofill.js
import React from 'react'
import PropTypes from 'prop-types'
import Styles from './searchbar.scss'
const AutoFill = (props) => {
console.log('proppppppsss', props)
const results = props.results || []
return (
<ul className={Styles.searchUl}>
{results.map(({ name, href }) => (
<li className={Styles.searchLi} key={href}>
<a className={Styles.searchA} href={href} target='_blank' rel='noopener noreferrer' key={href}>
{name}
</a>
</li>
))}
</ul>
)
}
AutoFill.propTypes = {
results: PropTypes.array
}
export default AutoFill
the Searchbar component in (index.js) that is being used in searchcontainer.js
import React from 'react'
import Styles from './searchbar.scss'
import Icon from '../../components/icon/icon'
import Search from '../../components/form-input/search'
import AutoFill from './autofill'
import PropTypes from 'prop-types'
export default class Searchbar extends React.Component {
constructor (props) {
super(props)
this.state = {
className: Styles.input,
icon: Styles.icon__wrapper,
value: []
}
this.input = React.createRef()
}
openInput = () => {
this.setState({
className: Styles.input__active,
icon: Styles.iconWidth
}, () => {
this.input.focus()
})
this.props.onOpen && this.props.onOpen()
}
closeInput = () => {
this.setState({
className: Styles.input,
icon: Styles.icon__wrapper
})
this.props.onClose && this.props.onClose()
}
handleChange = event => {
let value = event.target.value
this.setState({ value })
this.props.performSearch(value)
}
handleSubmit = event => {
event.preventDefault()
}
render () {
console.log('results', this.props.results)
console.log('state.value', this.state.value)
return (
<div>
<form onSubmit={this.handleSubmit} className={Styles.search}>
<div className={this.state.icon}>
<Icon className={Styles.icon__wrapper} iconName='faSearch' onClick={this.openInput} />
</div>
<Search autoComplete='off' value={this.state.value} onChange={this.handleChange} id='search' tabIndex='0' myref={input => { this.input = input }} className={this.state.className} onBlur={this.closeInput} placeholder='Search' />
</form>
<div>
<AutoFill results={this.props.results} />
</div>
</div>
)
}
}
Search.propTypes = {
performSearch: PropTypes.func,
results: PropTypes.array
}
When i try to refer to a what is in the json file from the search i receive the error,
GET http://localhost:3000/[object%20Object] 404 (Not Found)
And
about:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON
at position 0
The second error is fixed by doing
const parsedJson = response.text(
instead of
const parsedJson = response.json()
to get more information where/what the error takes place. But by doing this i receive the error,
searchcontainer.js:12 Uncaught (in promise) TypeError: Cannot read property 'results' of undefined
I've tried to run it from npm build instead of running it in a dev environment which didn't fix it.
I read that a mock url should work but then again i want to acces it from a file and not from a url?
Any help would be highly appreciated and looked into.
The problem is most likely in the fetch call. If you look at the error message GET http://localhost:3000/[object%20Object] 404 (Not Found)
You can see that it is trying to append an object to the URL localhost:3000/.
You are getting the Unexpected token < in JSON at position 0 error because the response of your fetch request is probably a 404 page. The < is most likely the first char of <html>
To access the JSON object in your React files, you can simply do an importation like so;
import * as autofillData from 'autofill.json';
It will be returned as a JSON object.
I believe you are using the isomorphic-fetch package wrongly, if you look at their source code, https://github.com/matthew-andrews/isomorphic-fetch/blob/master/fetch-npm-node.js#L5 , they are accepting a URL to make a call to the API URL which will return a promise or a JSON object depending on the implementation of the API that you are calling.
If you were to dive deeper into the open-source code here (https://github.com/matthew-andrews/isomorphic-fetch/blob/master/fetch-npm-node.js#L8) , you will notice that isomorphic-fetch package is using another package node-fetch to do their fetch call, which accepts the API URL and the method request options to call the API with. (As stated here; https://github.com/bitinn/node-fetch/blob/master/src/index.js#L34)
To continue with your test, perhaps this might be the solution you'd prefer?
import fetch from 'isomorphic-fetch';
import * as autofillData from 'autofill.json'; //test data
const FetchResults = event => {
return fetch('/https://jsonplaceholder.typicode.com/todos/1'') //mockURL, to be replaced with real API
.then(response => {
// const parsedJson = response.json(); // TODO: un-comment this line when the real API url is usable
const parsedJson = autofillData; // TODO: remove this line when mocking is done and the real API URL is ready
return parsedJson;
})
}
export default FetchResults;
To have a mock URL placeholder, I would suggest https://jsonplaceholder.typicode.com/ to prevent your fetch result to return an unexpected error during test mocking.
Hope this is helpful.
The question has been solved, The main issue was with defining const names such as const results = [] which should've been const results = props.results || [].
The code has been updated incase you have problems aswell.
Im trying to figure out why I can't seem to access the following piece of JSON data in my Vue Component.
My project is setup using Vue-cli with the Webpack template and is roughly setup as follows when I run into the problem.
Data JSON
This file contains several projects
projects: [
{
"slug": "page-url-slug",
"title": "Page title",
"image": {
"src": "/static/images/project-image.jpg",
"alt": "Alt text image"
}
}
]
Router
routes: [
{
path: '/work'
component: Work
},
{
path: '/work/:slug',
component: WorkItem,
props: (route) => ({
params: route.params
})
}
]
Component JS
export default {
props: [ 'params' ],
data () {
return {
project: {}
}
},
mounted () {
this.$http.get('/static/data.json')
.then((response) => {
let projects = response.data.projects
// Find data with same slug param
for (let i = 0; i < projects.length; i++) {
if (projects[i].slug === this.params.slug) {
this.project = projects[i]
return
}
}
// Else go back to parent route
this.$router.push('/work')
})
}
}
Component HTML
<template lang="html">
<div class="page">
<h1>{{ project.title }}</h1>
<img :src="project.image.src" alt="project.image.alt" />
</div>
</template>
When I try to access the project.image.src or the project.image.alt I keep getting the following error messages:
[Vue warn]: Error when rendering anonymous component at ...
Uncaught TypeError: Cannot read property 'src' of undefined
I am pretty new to Vuejs and I just can't seem to wrap my mind around the fact this happens.
You have to add null check as you are loading project asynchronously, like this:
<img :src="project && project.image && project.image.src" alt="project.image.alt" />
When this is being rendered, at that time project is not populated and it is still {}, which you set it in the beginning.