fetch data in nuxt3 not rendering in templete - javascript

I am trying to set api in nuxt 3 using this code:
<template>
<div>
<pre>{{ $data }}</pre>
<ul>
<li v-for="planet in planets" :key="planet.slug">
<NuxtLink :to="planet.slug">
{{ planet.title }}
</NuxtLink>
</li>
</ul>
</div>
</template>
<script>
export default {
async fetch() {
this.planets = await fetch('https://api.nuxtjs.dev/planets').then(res =>
res.json()
)
},
data() {
return {
planets: [],
}
},
}
</script>
but I only got this result in browser!!
"planets": []
I trid to use usefetch and useAsyncData but couldnot success
could anyone help me to know my mistake!

Here is how to perform data fetching using the Option API : https://nuxt.com/docs/getting-started/data-fetching#options-api-support
So in your case, this is how you should fetch your data.
<template>
<div>
<pre>{{ $data }}</pre>
<ul>
<li v-for="planet in planets" :key="planet.slug">
<NuxtLink :to="planet.slug">
{{ planet.title }}
</NuxtLink>
</li>
</ul>
</div>
</template>
<script>
export default defineNuxtComponent({
fetchKey: 'hello',
async asyncData() {
return {
planets: await $fetch('https://api.nuxtjs.dev/planets'),
};
},
});
</script>
Please, note that, as the doc says, using <script setup lang="ts"> is the recommended way of declaring Vue components in Nuxt 3.
You can find more information about it here: https://nuxt.com/docs/api/utils/define-nuxt-component

Related

nuxt content link using slug not found

I am trying nuxt content module. I created a directory called "articles" inside content folder cotaining 2 md files with some dummy data. then, inside pages I have a folder called "tutorials" which contains "_slug.vue" and index.vue
the index page shows only the title of the articles and it works fine. every title links to
the actual article using path/slug. the problem is that I get page not found. here is my code:
index.vue:
<template>
<div>
<article v-for="article of articles" :key="article.id">
<nuxt-link :to="`/tutorials/${article.slug}`">
{{ article.slug }}
</nuxt-link>
</article>
</div>
</template>
<script>
export default {
async asyncData({ $content, params }) {
const articles = await $content('articles', params.slug)
.only(['title', 'slug'])
.sortBy('createdAt', 'asc')
.fetch()
return {
articles,
}
},
}
</script>
_slug.vue:
<template>
<div>
<nuxt-content :document="article" />
</div>
</template>
<script>
export default {
async asyncData({ $content, params }) {
const article = await $content('articles', params.slug).fetch()
return {
article,
}
},
}
</script>
<style></style>
thank you.

Component that takes displays form data returns a warning. The warning is [Vue warn]: Component is missing template or render function

The component I am trying to get to display information is this one. It is called Addedinfo
<template>
<section class = "container">
<h1> My info </h1>
<ul>
<li v-for "info in information" :key="info.id"> {{ info.text }} </li>
</ul>
</section>
</template>
<script>
export default {
props: ["information"],
};
</script>
Addedinfo is nested in a component called Belay, which is here
<template>
<div style = "text-align: left;">
<h1>Enter Info</h1>
<added-info :information="filteredInfos"></added-info>
<add-information #add-info="another"> </add-information>
</div>
</template>
<script>
import { ref, computed } from 'vue';
import AddInformation from "../components/AddInformation.vue";
import AddedInfo from "../components/AddedInfo.vue";
export default{
components: {
AddInformation,
AddedInfo,
},
setup() {
const infos = ref([]);
const filteredInfos = computed(function() {
return infos.value.filter(
(info) => !info.text.includes("Angular") && !info.text.includes("React")
);
});
function another(text) {
const newVar = {
id: new Date().toISOString(),
text: text,
};
infos.value.push(newVar);
}
return {
filteredInfos: filteredInfos,
another: another
};
}
};
</script>
The component Addinfo (not included) takes information and the component Addedinfo is supposed to display it on Belay. Instead, upon entering information and submitting. I receive the following error-
[Vue warn]: Component is missing template or render function.
at <AddedInfo information= [] >
at <Belay onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <App>
How can I fix this?
Thanks.
In your AddInfo component template
<ul>
<li v-for "info in information" :key="info.id"> {{ info.text }} </li>
</ul>
v-for is missing the '=' sign. Should be:
<ul>
<li v-for="info in information" :key="info.id"> {{ info.text }} </li>
</ul>

Algolia vue instantsearch dynamically set search query

I have a search bar on the root component (App.vue). I want to enter a query and on #keyup.enter, it should redirect to the Search component view with the v-text-field input value. Redirection is used by using $router.replace because users might search for a different keyword from within the same route.
The code below work but only ONCE. If I enter a new search term, the URL changed but the results stay the same.
App.vue
<template>
<div>
<header>
<v-text-field #keyup.enter="goToSearchPage($event)"></v-text-field>
</header>
<v-main>
<router-view></router-view>
</v-main>
</div>
</template>
<script>
export default {
methods: {
goToSearchPage($event) {
this.$router.replace({
name: "Search",
query: { q: $event.target.value }
});
}
}
};
</script>
views/Search.vue
<template>
<div>
<ais-instant-search
index-name="dev_brunjar_products"
:search-client="searchClient"
:search-function="searchFunction"
>
<ais-hits>
<ul slot-scope="{ items }">
<li v-for="item in items" :key="item.objectID">
{{ item.name }}
</li>
</ul>
</ais-hits>
</ais-instant-search>
</div>
</template>
<script>
import algoliasearch from "algoliasearch/lite";
export default {
data() {
return {
searchClient: algoliasearch(
process.env.VUE_APP_ALGOLIA_APP_ID,
process.env.VUE_APP_ALGOLIA_SEARCH_KEY
)
};
},
methods: {
// According to Algolia's doc, this should be inside data instead of methods
// https://www.algolia.com/doc/api-reference/widgets/instantsearch/vue/#widget-param-search-function
// But doing so, I wouldn't be able to get this.$route.query.q
searchFunction(helper) {
var query = this.$route.query.q;
if (query) {
helper.setQuery(query).search();
}
}
}
};
</script>
What I've tried
Did a hack-ish way (Test 1) to solve it but didn't work (which I'm glad, because it doesn't feel right). Below was the non-working code addition to the Search component. Created computed & watch property of query which get its data from this.$route.query.q and algoliaHelper data assigned with AlgoliaSearchHelper when the searchFunction first load.
When I typed a new search term, the watcher works and the query indeed changed. Despite that, calling the helper and setting its query with the new term within the watcher did not change the results from Algolia.
Then I used Routing URLs (Test 2) to the ais-instant-search and it still didn't solve the issue. Maybe I'm implementing it wrong? I really tried to understand Algolia's doc and it's just too hard to digest.
views/Search.vue - Test 1 (Failed)
<template>
<div>
<ais-instant-search
index-name="dev_brunjar_products"
:search-client="searchClient"
:search-function="searchFunction"
>
<ais-hits>
<ul slot-scope="{ items }">
<li v-for="item in items" :key="item.objectID">
{{ item.name }}
</li>
</ul>
</ais-hits>
</ais-instant-search>
</div>
</template>
<script>
import algoliasearch from "algoliasearch/lite";
export default {
data() {
return {
searchClient: algoliasearch(
process.env.VUE_APP_ALGOLIA_APP_ID,
process.env.VUE_APP_ALGOLIA_SEARCH_KEY
),
algoliaHelper: null
};
},
computed: {
query() {
return this.$route.query.q;
}
},
watch: {
query(newQuery) {
this.algoliaHelper.setQuery(newQuery).search();
}
},
methods: {
searchFunction(helper) {
if (!this.algoliaHelper) {
this.algoliaHelper = helper;
}
if (this.query) {
helper.setQuery(this.query).search();
}
}
}
};
</script>
views/Search.vue - Test 2 (Failed)
<template>
<div>
<ais-instant-search
index-name="dev_brunjar_products"
:search-client="searchClient"
:search-function="searchFunction"
:routing="routing"
>
<ais-hits>
<ul slot-scope="{ items }">
<li v-for="item in items" :key="item.objectID">
{{ item.name }}
</li>
</ul>
</ais-hits>
</ais-instant-search>
</div>
</template>
<script>
import { history as historyRouter } from "instantsearch.js/es/lib/routers";
import { singleIndex as singleIndexMapping } from "instantsearch.js/es/lib/stateMappings";
import algoliasearch from "algoliasearch/lite";
export default {
data() {
return {
searchClient: algoliasearch(
process.env.VUE_APP_ALGOLIA_APP_ID,
process.env.VUE_APP_ALGOLIA_SEARCH_KEY
),
routing: {
router: historyRouter(),
stateMapping: singleIndexMapping("instant_search")
}
};
},
methods: {
searchFunction(helper) {
if (this.query) {
helper.setQuery(this.query).search();
}
}
}
};
</script>
I would appreciate it if you guys know how to solve this issue.
https://codesandbox.io/s/github/algolia/doc-code-samples/tree/master/Vue%20InstantSearch/routing-vue-router?file=/src/views/Home.vue
This is an example using vue router. I guess this might be what you're looking for.
Please let us know if it works for you.
Hope you where able to solve this since it's been a long time since you asked. But, in order to make it work you have to put searchFunction(helper) inside data() as shown in the docs: https://www.algolia.com/doc/api-reference/widgets/instantsearch/vue/#widget-param-search-function

v-for returns error when i want to write arrays

I want my array data to be shown in the list, but I'm seeing the following error:
error: Elements in iteration expect to have 'v-bind:key' directives (vue/require-v-for-key) at src\components\Kubismyk.vue:5:9:
My component:
<template>
<div>
<h1>{{ title }}</h1>
<ul>
<li v-for="ninja in ninjas">{{ ninja }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
title:'hello world',
ninjas: ['yoshi','mario','ryu']
}
}
}
</script>
You need to bind a v-key when using v-for:
<ul v-for="ninja in ninjas" v-bind:key="ninja.id">
<li>{{ ninja.name }}
</ul>```
You need a unique key for v-key when using v-for loops so that Vue can track each node's identity. You could use index in this case:
<li v-for="(ninja, index) in ninjas" :key="index">
You can discover more information about this linter rule in vue/require-v-for-key docs.

Vue and firebase database

<template lang="html">
<div class="">
<ul>
<li>{{ this.anArray.model }}</li>
</ul>
</div>
</template>
<script>
import db from '../firebase/init.js';
var link = db.ref('cars').child('-KoKST99e110OZs6g111');
var thedata = link.once('value').then(function(snapshot){return snapshot.val()});
export default {
name: 'view',
firebase: {
anArray:thedata
}
}
</script>
I trying to get the object inside that path on firebase database but is answer unknown. the connection is good, the problem is how Im doing it. Help!

Categories