I start to learn the alpine js combine with the tailwind. But I don't know how to print the fetch result from json response, try with this
<div x-data="orderSearch()"
class="container mx-auto py-6 px-4"
>
<div class="flex border-2 border-gray-200 rounded">
<input type="text" class="px-4 py-2 w-100 uppercase" placeholder="Search" name="orderidSearch"
x-model="orderidSearch">
<button #click="fetchFulfillment()" class="px-2 py-1 text-white bg-blue-500 rounded hover:bg-green-600">Cari Fulfillment</button>
but return the error in console alpine.js:115 Alpine Error: "TypeError: Cannot read properties of undefined (reading 'inv_id')"
Anyone know how to print the result inside div?
My js function:
function orderSearch() {
return {
orderidSearch: '',
// other default properties
orders: [],
fetchOrders() {
this.isLoading = true;
fetch(`check.php?order_id=${this.orderidSearch}`)
.then(res => res.json())
.then(data => {
this.isLoading = false;
this.orders = data.orders;
console.log(data);
});
console.log(this.orders);
},
....
json return data:
{"data":[{"inv_id":"8768768768"]}
The problem occurs because you will get an iterable object. I rewrite your code a little bit and put the function inline to show the first entry. If you have a collection then build your loop to sow every item.
<div
class="container mx-auto py-6 px-4"
x-data="{
orders: null,
isLoading: false,
orderSearch() {
this.isLoading = true;
fetch(`check.php?order_id=${this.orderidSearch}`)
.then((response) => response.json())
.then((json) => this.orders = json);
}
}" x-init="orderSearch()">
<p x-text="orders[0].inv_id"></p>
</div>
Related
The page for my web3-based event application works fine until I go into my "past events" and click "attendees." When I do that, I get Syntax error: Unexpected token.
The issue is specifically on line 86 of my code, for (let i = 0; < event.confirmedAttendees.length; i++) {. In VS Code, I have 4 errors, all of which point to this line. The errors are "parsing error: unexpected token", 2 "identifier expected" errors, and 1 "expression expected."
I've checked the code against the GitHub repo I forked the entire project file from, edited it, and now it all matches.
I'm new to coding with no previous JS experience. I've been scratching my head on this one all day. I have no idea what the issue is.
Here is the entire code from my [id].js file. The issue is with line 86.
import { useState, useEffect } from "react";
import Head from "next/head";
import Link from "next/link";
import { gql } from "#apollo/client";
import client from "../../../apollo-client";
import { ConnectButton } from "#rainbow-me/rainbowkit";
import { useAccount } from "wagmi";
import connectContract from "../../../utils/connectContract";
import formatTimestamp from "../../../utils/formatTimestamp";
import DashboardNav from "../../../components/DashboardNav";
import Alert from "../../../components/Alert";
function PastEvent({ event }) {
const { data: account } = useAccount();
console.log("event", event);
const [success, setSuccess] = useState(null);
const [message, setMessage] = useState(null);
const [loading, setLoading] = useState(null);
const [mounted, setMounted] = useState(false);
const confirmAttendee = async (attendee) => {
try {
const rsvpContract = connectContract();
if (rsvpContract) {
const txn = await rsvpContract.confirmAttendee(event.id, attendee);
setLoading(true);
console.log("Minting...", txn.hash);
await txn.wait();
console.log("Minted -- ", txn.hash);
setSuccess(true);
setLoading(false);
setMessage("Attendance has been confirmed.");
} else {
console.log("Ethereum object doesn't exist!");
}
} catch (error) {
setSuccess(false);
// setMessage(
// `Error: ${process.env.NEXT_PUBLIC_TESTNET_EXPLORER_URL}tx/${txn.hash}`
// );
setMessage("Error!");
setLoading(false);
console.log(error);
}
};
const confirmAllAttendees = async () => {
console.log("confirmAllAttendees");
try {
const rsvpContract = connectContract();
if (rsvpContract) {
console.log("contract exists");
const txn = await rsvpContract.confirmAllAttendees(event.id, {
gasLimit: 300000,
});
console.log("await txn");
setLoading(true);
console.log("Mining...", txn.hash);
await txn.wait();
console.log("Mined -- ", txn.hash);
setSuccess(true);
setLoading(false);
setMessage("All attendees confirmed successfully.");
} else {
console.log("Ethereum object doesn't exist!");
}
} catch (error) {
setSuccess(false);
// setMessage(
// `Error: ${process.env.NEXT_PUBLIC_TESTNET_EXPLORER_URL}tx/${txn.hash}`
// );
setMessage("Error!");
setLoading(false);
console.log(error);
}
};
function checkIfConfirmed(event, address) {
// console.log(event.confirmedAttendees);
for (let i = 0; < event.confirmedAttendees.length; i++) {
let confirmedAddress = event.confirmedAttendees[i].attendee.id;
if (confirmedAddress.toLowercase() == address.toLowercase()) {
return true;
}
}
return false;
}
useEffect(() => {
setMounted(true);
}, []);
return (
mounted && (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<Head>
<title>My Dashboard | web3rsvp</title>
<meta name="description" content="Manage your events and RSVPs" />
</Head>
<div className="flex flex-wrap py-8">
<DashboardNav page={"events"} />
<div className="sm:w-10/12 sm:pl-8">
{loading && (
<Alert
alertType={"loading"}
alertBody={"Please wait"}
triggerAlert={true}
color={"white"}
/>
)}
{success && (
<Alert
alertType={"success"}
alertBody={message}
triggerAlert={true}
color={"palegreen"}
/>
)}
{success === false && (
<Alert
alertType={"failed"}
alertBody={message}
triggerAlert={true}
color={"palevioletred"}
/>
)}
{account ? (
account.address.toLowerCase() ===
event.eventOwner.toLowerCase() ? (
<section>
<Link href="/my-events/past">
<a className="text-indigo-800 text-sm hover:underline">
← Back
</a>
</Link>
<h6 className="text-sm mt-4 mb-2">
{formatTimestamp(event.eventTimestamp)}
</h6>
<h1 className="text-2xl tracking-tight font-extrabold text-gray-900 sm:text-3xl md:text-4xl mb-8">
{event.name}
</h1>
<div className="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
<div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
<table className="min-w-full divide-y divide-gray-300">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"
>
Attendee
</th>
<th
scope="col"
className="text-right py-3.5 pl-3 pr-4 sm:pr-6"
>
<button
type="button"
className="items-center px-4 py-2 border border-transparent text-sm font-medium rounded-full text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
onClick={confirmAllAttendees}
>
Confirm all
</button>
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200 bg-white">
{event.rsvps.map((rsvp) => (
<tr key={rsvp.attendee.id}>
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
{rsvp.attendee.id}
</td>
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
{checkIfConfirmed(event, rsvp.attendee.id) ? (
<p>Confirmed</p>
) : (
<button
type="button"
className="text-indigo-600 hover:text-indigo-900"
onClick={() =>
confirmAttendee(rsvp.attendee.id)
}
>
Confirm attendee
</button>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</section>
) : (
<p>You do not have permission to manage this event.</p>
)
) : (
<ConnectButton />
)}
</div>
</div>
</div>
)
);
}
export default PastEvent;
export async function getServerSideProps(context) {
const { id } = context.params;
const { data } = await client.query({
query: gql`
query Event($id: String!) {
event(id: $id) {
id
eventID
name
eventOwner
eventTimestamp
maxCapacity
totalRSVPs
totalConfirmedAttendees
rsvps {
id
attendee {
id
}
}
confirmedAttendees {
attendee {
id
}
}
}
}
`,
variables: {
id: id,
},
});
return {
props: {
event: data.event,
},
};
}
It looks like you missed the i in the for loop check in this function:
function checkIfConfirmed(event, address) {
// console.log(event.confirmedAttendees);
for (let i = 0; < event.confirmedAttendees.length; i++) {
let confirmedAddress = event.confirmedAttendees[i].attendee.id;
if (confirmedAddress.toLowercase() == address.toLowercase()) {
return true;
}
}
return false;
}
Take a look at the second line in your function:
// currently:
for (let i = 0; < event.confirmedAttendees.length; i++)
// missing i in the check, should be:
for (let i = 0; i < event.confirmedAttendees.length; i++)
Let me know if anything seems unclear regarding for loops!
stuck while implementing [this quill to pdf][1] package to my laravel vue3 project. It is working fine to use, but when i try to save the rich text as pdf it i am getting stucked.
<form #submit.prevent="store">
<div class="flex flex-wrap -mb-8 -mr-6 p-8">
<text-input v-model="form.title" :error="form.errors.title" class="pb-8 pr-6 w-full lg:w-1/2" label="title" />
</div>
<div class="-mb-8 -mr-6 p-8 h-100">
<QuillEditor theme="snow" :toolbar="modules.toolbar" v-model:content="form.content" />
</div>
<div class="flex items-center justify-end px-8 py-4 bg-gray-50 border-t border-gray-100">
<loading-button :loading="form.processing" class="btn-indigo" type="submit">Create Organization</loading-button>
</div>
</form>
<button #click="saveAsFile()" class="btn-indigo">Get Pdf</button>
and vue js goes:
data() {
return {
loading: true,
form: this.$inertia.form({
title: null,
content: null,
}),
}
},
setup: () => {
//setTimeout(true, 4000)
var toolbarOptions = [['bold', 'italic'], ['link', 'image']];
const modules = {
name: 'blotFormatter',
toolbar: toolbarOptions,
module: BlotFormatter,
options: {/* options */}
}
return { modules }
},
methods: {
store() {
this.form.post('/templates')
},
async saveAsFile(){
const quillInstance = new Quill()
const delta = quillInstance.getContents(this.form.content); // gets the Quill delta
const pdfAsBlob = await pdfExporter.generatePdf(delta); // converts to PDF
saveAs(pdfAsBlob, 'pdf-export.pdf'); // downloads from the browser
}
},
i keep getting the error saying "Invalid Quill container" help me out please if you can!
I'm using snipcart in a nextjs with strapi app.
I receive an error when processing a payment :
A 'cart-confirmation' error occured in Snipcart. Reason:
'product-crawling-failed'
[Details] We have not been able to find item with id '59' at
'https://cmeditions.fr/products/selfless'. Please make sure the
product is correctly defined.
and :
An attempt to create an order with invalid products has been made.
Don't forget you can't add/update items attributes in the cart
dynamically with javascript as it will cause crawling issues
It works when data-item-id is replaced by a static value but not with somthing like {product.id}
Here is my component [sulg].js :
const ProductPage = ({ product }) => {
const router = useRouter()
if (router.isFallback) {
return <div>Loading product...</div>
}
return (
<div className="carousel-container m-6 grid grid-cols-1 gap-4 mt-8 items-start">
<Head>
<title>{product.title}</title>
</Head>
<div className="rounded-t-lg pt-2 pb-2 m-auto h-auto">
<EmblaCarousel {...product} />
</div>
<div className="w-full p-5 flex flex-col justify-between">
<div>
<h4 className="mt-1 font-semibold leading-tight truncate text-slate">
<span className="uppercase text-lg font-bold">{product.title}</span>
<br />
{product.author}
</h4>
<LanguageDesc {...product} />
</div>
<div className="flex flex-col md:flex-row">
<div className="mt-4 font-semibold leading-tight truncate text-slate">
<p>{product.year}</p>
<p>Format: {product.size}</p>
<p>Printing: {product.technic}</p>
<p>Paper: {product.medium}</p>
<p>{product.page}</p>
<p>{product.copies} copies</p>
<p>{product.price}€</p>
</div>
{product.status === "published" ? (
<button
className="snipcart-add-item mt-4 ml-16 self-center bg-slate border border-gray-200 d hover:shadow-lg hover:bg-brique focus:outline-none text-white font-semibold leading-none py-2 px-4 w-20 h-20 rounded-full"
data-item-id={product.id}
data-item-price={product.price}
data-item-url={router.asPath}
data-item-description={product.description}
data-item-image={getStrapiMedia(
product.image.formats.thumbnail.url
)}
data-item-name={product.title}
v-bind="customFields"
>
Add to cart
</button>
) : (
<div className="text-center mr-10 mb-1" v-else>
<div
className="p-2 bg-indigo-800 items-center text-indigo-100 leading-none lg:rounded-full flex lg:inline-flex"
role="alert"
>
<span className="flex rounded-full bg-indigo-500 uppercase px-2 py-1 text-xs font-bold mr-3">
Coming soon...
</span>
<span className="font-semibold mr-2 text-left flex-auto">
This article is not available yet.
</span>
</div>
</div>
)}
</div>
</div>
</div>
)
}
export async function getStaticProps({ params }) {
const product = await getProduct(params.slug)
return { props: { product } }
}
export async function getStaticPaths() {
const products = await getProducts()
return {
paths: products.map((_product) => {
return {
params: { slug: _product.slug },
}
}),
fallback: true,
}
}
export default ProductPage
EDIT
I tried to return a json to the validator, but I think it isn't right
/api/products.js
import { getProducts } from "../../utils/api"
// eslint-disable-next-line import/no-anonymous-default-export
export default async function (_req, res) {
return new Promise((resolve) => {
getProducts()
.then((response) => {
res.statusCode = 200
res.setHeader("Content-Type", "application/json")
res.setHeader("Cache-Control", "max-age=180000")
res.end(JSON.stringify(response))
resolve()
})
.catch((error) => {
res.json(error)
res.status(405).end()
resolve() // in case something goes wrong in the catch block (as vijay commented)
})
})
}
api.js
export function getStrapiURL(path) {
return `${
process.env.NEXT_PUBLIC_STRAPI_API_URL || "http://localhost:1337"
}${path}`
}
// Helper to make GET requests to Strapi
export async function fetchAPI(path) {
const requestUrl = getStrapiURL(path)
const response = await fetch(requestUrl)
const data = await response.json()
return data
}
export async function getCategories() {
const categories = await fetchAPI("/categories")
return categories
}
export async function getCategory(slug) {
const categories = await fetchAPI(`/categories?slug=${slug}`)
return categories?.[0]
}
export async function getProducts() {
const products = await fetchAPI("/products")
return products
}
export async function getProduct(slug) {
const products = await fetchAPI(`/products?slug=${slug}`)
return products?.[0]
}
export async function getLibrairies() {
const librairies = await fetchAPI("/librairies")
return librairies
}
export async function getLibrairie(slug) {
const librairies = await fetchAPI(`/librairies?slug=${slug}`)
return librairies?.[0]
}
It sounds like you will need to validate the orders with a JSON file that you can assign to the buy button with data-item-url.
You can read the full guide here:
https://docs.snipcart.com/v3/setup/order-validation#json-crawler.
Let me know if that helps!
It finally wasn't a matter of JSON crawler but something to see with the domain on the snipcart dashboard. I had to put the vercel.app domain first and my own domain name as a subdomain. It worked when I changed this. This is the only explaination I got
I wrote a graphql query to get recent posts for a blog app in NextJs in other to display them as widgets
export const getRecentPosts = async () =\> {
const query = gql`
query MyQuery {
posts(orderBy: createdAt_ASC
last: 3 )
{title
featuredImage {url}
createdAt
slug
}
}
`;
const result = await request(graphAPI, query);
return result.posts;
};
but i keep getting a "Cannot read properties of undefined (reading 'document')" error
and it keeps displaying this error
NextJs error
I imported the function into the component
function PostWidget({ categories, slug }) {
const [relatedPosts, setRelatedPosts] = useState([]);
useEffect(() => {
if (slug) {
getSimilarPosts(categories, slug).then((result) => {
setRelatedPosts(result);
});
} else {
getRecentPosts().then((result) => {
setRelatedPosts(result);
});
}
}, [slug]);
console.log(relatedPosts)
return (
<div className="bg-white shadow-lg rounded-lg p-8 mb-8">
<h3 className="text-xl mb-4 font-semibold border-b p-4">
{slug ? "Related posts" : "Recent posts"}
</h3>
{
relatedPosts.map((post) => (
<div key={post.title} className="flex items-center w-full mb-4">
<div className="w-16 flex-none">
<img
alt={post.title}
height="60px"
width="60px"
className="align-middle rounded-full"
src={post.featuredImage.url}
/>
</div>
</div>
))
}
</div>
)
}
but it gives an empty array when i console.log the related posts
I am new to Vuejs and would need some help, please. I am calling a component in order to create a 'member'. While calling this component and passing the member data, the component raises an error related to one of the functions inside. The issue seems that the member data is not being initially fulfilled considering that the member data is being fetched via an API. I have tried converting the function which causes the error to Asynchronous but that does not seem to work either. Below please find some code snippets for my issue.
Home.vue
<Member :member="memb" />
data() {
return {
memb: {},
};
},
//Method fetching the member from api
async fetchMember(memberId) {
const res = await axios.get(`http://localhost:3000/members/${memberId}`, { apiHeaders });
return res.data;
},
//Method which fetched the member
async created() {
this.memb = await this.fetchMember(1);
},
Member.vue
<template>
<div class="m-auto">
<p>Name: {{ member.name }}</p>
<p>Surname: {{ member.surname }}</p>
<p>Date of Birth: {{ formatDob(member.dob) }}</p>
<p>Age: {{ calculateAge(member.dob) }}</p>
<p>Relationship: {{ member.relationship }}</p>
<button class="bg-blue-500 py-1 px-4 rounded-md text-gray-100 text-sm mx-1 mt-3 font-bold" #click="$emit('get-member-id', member.id)">Update</button>
<button class="bg-red-500 py-1 px-4 rounded-md text-gray-100 text-sm mx-1 mt-3 font-bold" #click="$emit('delete-member', member.id)">Delete</button>
</div>
</template>
<script>
export default {
name: 'Member',
props: {
member: Object,
},
methods: {
// Converting the date of birth format
formatDob(dob) {
return dob.split('/').reverse().join('/');
},
// Calculating the date of birth by comparing today's date with the member's date of birth
calculateAge(dob) {
const birthdate = new Date(dob);
const todayDate = new Date();
const difference = todayDate - birthdate; // This is the difference in milliseconds
return Math.floor(difference / 31557600000);
},
},
};
</script>
The issue that I am getting is related to calling the formatDOB from the Member component. In fact the issue says: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'split')
Thanks in advance.
Will be cool if we can implement a progress indicator meant for informing the users about loading activity of data
Once the member data loads, you can start showing the member component and hide the progress indicator.
Pseudocode would look like something below.
<Member v-if="isLoaded" :member="memb" />
<ProgressBar v-if="!isLoaded" />
<script>
export default {
data: (() => {
return {
isLoaded: false,
memb: null
}
})
async mounted() {
this.isLoaded = false;
this.memb = await this.fetchMember(1);
this.isLoaded = true;
}
}
</script>