strapi-girdsome starter issues - strapi

When following official strapi-gridsome tutorial, trying to create new pages from ID numbers
Steps to reproduce:
npm: '6.14.9',
node: '14.14.0',
strapi '3.5.0'
Expected result:
http://localhost:8080/categories/1
should show data from API but instead shows 404 page
Actual result:
When running gridsome develop...
ERROR Failed to compile with 1 errors
This dependency was not found:
..\my-gridsome-site\src\templates\Category.vue in ./src/.temp/routes.js
gridsome.server.js
module.exports = function (api) {
api.loadSource(({ addCollection }) => {
// Use the Data Store API here: https://gridsome.org/docs/data-store-api/
})
api.createPages(async ({ graphql, createPage }) => {
const { data } = await graphql(`
{
allStrapiCategory {
edges {
node {
id
name
}
}
}
}
`);
const categories = data.allStrapiCategory.edges;
categories.forEach(category => {
createPage({
path: `/categories/${category.node.id}`,
component: './src/templates/Category.vue',
context: {
id: category.node.id,
},
});
});
});
};
src\templates\category.vue
<template>
<Layout>
<div>
<h1>{{ $page.category.name }}</h1>
<ul>
<li v-for="restaurant in $page.category.restaurants">{{ restaurant.name }}</li>
</ul>
</div>
</Layout>
</template>
<page-query>
query Category($id: ID!) {
category: strapiCategory(id: $id) {
name
restaurants {
id
name
}
}
}
</page-query>

I had this same issue.
I was running yarn develop and hot-reload was working for general playing with data, layout etc. But when editing gridsome.server.js these changes aren't reflected.
This is solved by re-starting the server. And now you'll have your dynamic pages.

Related

Vue js with laravel not geting api data and response

this is Vue js component please help me to get data in template. getting data from vue js api in console i got undefined. Not getting blogList Data please help to get blog list data.
my api is correct and fetch data.
<template>
<div v-for="blog in blogList">
Hii i am {{ blog.name }} , {{ blog.mail }}
</div>
</template>
<script>
import ApiRequest from "../../js/api-request";
export default {
data() {
return {
blogList: '',
};
},
created() {
const request = new ApiRequest('/api/blog/list', (blogList) => {
this.blogList = blogList;
console.log(blogList);
}, () => {
//
});
request.get();
}
};
</script>

Page load without refresh in svelte and dynamic routing

What is the best way to load a page without refreshing using graphql and dynamic routing.
I have a file called kindergarten that loads perfectly without refreshing the whole page :
<script context="module">
import { gql, GraphQLClient } from 'graphql-request'
export async function load() {
const graphcms = new GraphQLClient(import.meta.env.VITE_GRAPHCMS_URL, {
headers: {},
})
const query = gql`
query MyQuery {
terms(where: { taxonomies: CATEGORY }) {
nodes {
slug
name
termTaxonomyId
}
}
}
`
const { terms } = await graphcms.request(query)
return {
props: {
posts: terms.nodes,
},
}
}
</script>
<script>
import { SITE_NAME } from '$lib/store.js'
let date = new Date()
const [month, day, year] = [
date.getMonth() + 1,
date.getDate(),
date.getFullYear(),
]
export let posts = []
</script>
<svelte:head>
<title>Sample Title - {SITE_NAME}</title>
<meta
name="description"
content="Sample description [Update: {year}/{month}/{day}]" />
</svelte:head>
{#each posts as post (post.termTaxonomyId)}
<a
tax-id={post.termTaxonomyId}
href="/kindergarten/province/{post.slug}"
target="blank">
{post.name}
</a>
<br />
{/each}
and also I have another page called [slug].svelte :
<script context="module">
import { gql, GraphQLClient } from 'graphql-request'
export async function load(ctx) {
let slug = ctx.page.params.slug
const graphcms = new GraphQLClient(import.meta.env.VITE_GRAPHCMS_URL, {
headers: {},
})
const query = gql`
query MyQuery {
terms(where: { taxonomies: CATEGORY, slug: "${slug}" }) {
nodes {
name
description
}
}
}
`
const { terms } = await graphcms.request(query)
return { props: { slug, post: terms.nodes } }
}
</script>
<script>
import { SITE_NAME } from '$lib/store.js'
export let slug
export let post
</script>
<svelte:head>
<title>{post[0].name} - {SITE_NAME}</title>
</svelte:head>
<h1>Slug : {slug}</h1>
{#each post as data}
<p>Name: {data.name}</p>
<br />
{#if data.description}
<p>Description: {data.description}</p>
{:else}
<p>Ther is no Description</p>
{/if}
{/each}
When I click a link on kindergarten page it goes to the subpage but refreshes the whole site.
How can I optimize the [slug].svelte file to prevent refreshing the page?
As I'm new to Svelte and Sveltekit, any ideas for optimizing the whole code is appreciated.
You're linking to a new page, so it makes sense it refreshes, because it's going to a whole new page ([slug].svelte). It sounds like you're trying to load data into your kindergarten.svelte page? In that case, make a component, not a page, where you can pass in data to the component, and the component will be updated, rather than the entire page. Check out an example from the docs here: https://svelte.dev/tutorial/component-bindings

How to pass data from a GraphQL query onto a programmatically generated page?

I am a beginner with GraphQL and I'm having trouble accessing the data from my GraphQL query. I have been able to console log the data, which shows that the query is working but when I try to access it I get the error message "Cannot read property 'page_name' of undefined"
See images of variations I have tried:
https://i.ibb.co/6JS20K5/Graph-QL-1.png
https://i.ibb.co/wMq1V6g/Graph-QL-2.png
https://i.ibb.co/MN5g5Pk/Graph-QL-3.png
I can see my data in the console when I use:
console.log(data.allPagesJson.edges)
My understanding is that, in order to access the exact data I need, I should use:
console.log(data.allPagesJson.edges.node.page_name)
However, this now gives me the error message "Cannot read property 'page_name' of undefined". The reason for this seems to be that "node" is undefined but I'm not sure why...
This is my pages template:
import React from "react"
import { graphql } from "gatsby"
export default ({ data }) => {
console.log(data.allPagesJson.edges.node.page_name)
return (
<div>
<h1>Test</h1>
</div>
)
}
export const query = graphql`
query($page_url: String!) {
allPagesJson(filter: { page_url: { eq: $page_url } }) {
edges{
node{
page_url
page_name
}
}
}
}
`
This is my pages gatsby-node.js file:
const path = require(`path`)
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return graphql(`
{
allPagesJson {
edges {
node {
page_url
}
}
}
}
`
).then(result => {
result.data.allPagesJson.edges.forEach(({ node }) => {
createPage({
path: node.page_url,
component: path.resolve(`./src/templates/product-pages.js`),
context: {
page_url: node.page_url,
},
})
})
})
}
I managed to work it out. I can access the data using:
<div>
{data.allPagesJson.edges.map(({ node }) => (
<div key={node.id}>
<h1>{node.page_name}</h1>
</div>
))}
</div>

Page doesn't update on pagination click in Laravel SPA

I am creating an SPA with Laravel and VUEJS. Everything works well:
- The routing changes accurately from /people to /people?page=2
- The data in the table displays correctly.
But, the problem is, if I click the pagination, the data inside the table doesn't update. The URL is updated /people?page=3 but records are still the same. Here are my codes below.
routes.js
export default[
{
path:'/people?page=:page',
component: ListPeople,
name: 'people.paginate',
meta:{
title: 'Paginate'
}
},
{
path: '/people',
component: ListPeople,
name: 'people.list',
meta: {
title: 'People List',
}
},
ListPeople.vue
I have listed here the table.
<template>
<div class="container">
<h1>People List</h1>
<vue-table v-bind="{data:people.data,columns}"></vue-table>
<vue-pagination :pagination="people"
#paginate="getPeople"
:offset="4">
</vue-pagination>
</div>
Paginate.vue
From my pagination, I have something like below:
<template>
<!-- more codes here -->
<router-link class="page-link" :to="{ name:'people.paginate', params:{ page: page }}">{{ page }}</router-link>
<!-- more codes here -->
</template>
<script>
export default{
props: {
pagination: {
type: Object,
required: true
},
offset: {
type: Number,
default: 4
}
},
computed: {
pagesNumber() {
if (!this.pagination.to) {
return [];
}
let from = this.pagination.current_page - this.offset;
if (from < 1) {
from = 1;
}
let to = from + (this.offset * 2);
if (to >= this.pagination.last_page) {
to = this.pagination.last_page;
}
let pagesArray = [];
for (let page = from; page <= to; page++) {
pagesArray.push(page);
}
return pagesArray;
}
},
methods : {
changePage(page) {
this.pagination.current_page = page;
this.$emit('paginate',page);
}
}
}
</script>
You need to add a key to your vue-table component that changes when the pagination changes.
<vue-table v-bind="{data:people.data,columns}" :key="currentPage" ></vue-table>
So in your ListPeople component perhaps in your getPeople method update the key as you paginate.
data(){
return:{
currentPage: 1;
}
}
methods:{
getPeople(page){
//.. do something
this.currentPage = page;
}
}
If you include a key on a child component, when the parent template renders, Vue sets a getter/setter on the key and automatically adds it to the watcher instance of the component. So when the key changes it automatically rerenders the child component. Without the key the child component will remain in its cached state.

Get 2 data from API laravel

i have 2 data from API
1. Category Food
2. Finish Good
how can i show 2 data from API in 1 page vue,
I only can show 1 data from API
this is what i tried
export default {
data(){
items:[],
finish_goods:[],
created() {
let uri = 'http://192.168.10.75:8000/api/finish_goods'; // Data 1
this.axios.get(uri).then(response => {
this.items = response.data.data;
});
},
created() {
let uri = 'http://192.168.10.75:8000/api/cat_foods'; // Data 2
this.axios.get(uri).then(response => {
this.finish_goods = response.data.data;
});
}
},
methods: {}
}
You're along the right lines, but it looks like your template syntax is a bit messed up...
// Make sure axios is installed via npm, you can skip this step
// if you've declared window.axios = axios somewhere in your app...
import axios from 'axios';
export default {
// Data must be a function that returns the initial state object...
data() {
return {
finishGoods: [],
catFoods: []
};
},
// Created is a hook and can only be defined once, think of it like an event listener...
created() {
let finishGoodsUri = 'http://192.168.10.75:8000/api/finish_goods';
// Fetch finish goods, note that I'm not calling this.axios...
axios.get(finishGoodsUri).then(response => {
this.finishGoods = response.data.data;
});
let catFoodsUri = 'http://192.168.10.75:8000/api/cat_foods';
// Fetch cat foods...
axios.get(catFoodsUri).then(response => {
this.catFoods = response.data.data;
});
}
}
Now in your template you can do the following:
<template>
<div>
<div v-for="finishGood in finishGoods">
{{ finishGood.attribute }}
</div>
<div v-for="catFood in catFoods">
{{ catFood.attribute }}
</div>
</div>
</template>
my advice, combine the API as 1
created() {
let uri = 'http://192.168.10.75:8000/api/combine_data'; // sample
this.axios.get(uri).then(response => {
this.finish_goods = response.data.data.goods;
this.items = response.data.data.foods;
});
}

Resources