vue3 componentAPI, I have a question about object manipulation - vuejs3

I am new to vue3.
First, please look at the image below.
The code for this image is below.
const category = ref('')
onMounted(() => {
axios.get('/api/top')
.then((res) => {
category.value = res.data
console.log(category) // line12
console.log(category.value) // line13
console.log(category.value[0]) // line14
console.log(category.value[0].title) // line15
})
})
I don't know why console.log(category.value[0]) equall Proxy {id: 13, pos: null, title: 'dfgh', created_at: '2022-11-02T13:52:25.000000Z', updated_at: '2022-11-02T13:52:25.000000Z'}.
I respond to one record in the server side and catch this record in the browser.
please tell me value[0] meaning.
Thank you!
I want to display title of record but, in template tag {{ category.value[0].title }} occur error. It doesn't make any sense.

Related

Adding a new item when using useSWRInfinite pushes other items out of the list

I am building a comment system where new replies are added to the start (top) of the list. The pagination is cursor-based.
At the moment, I use mutate to add the newly created comment as its own page to the front of the list.:
const {
data: commentsPages,
: commentsPagesSize,
: setCommentsPagesSize,
//TODO: Not true on successive page load. But isValidating refreshes on refetches
isLoading: commentsLoading,
error: commentsLoadingError,
mutate: mutateCommentPages,
} = useSWRInfinite(
getPageKey,
([blogPostId, lastCommentId]) => BlogApi.getCommentsForBlogPost(blogPostId, lastCommentId));
<CreateCommentBox
blogPostId={blogPostId}
title="Write a comment"
onCommentCreated={(newComment) => {
const updatedPages = commentsPages?.map(page => {
const updatedPage: GetCommentsResponse = { comments: [newComment, ...page.comments], paginationEnd: page.paginationEnd };
return updatedPage;
})
mutateCommentPages(updatedPages, { revalidate: false });
}}
/>
The problem is, SWR immediately starts revalidating the list and pushes the comment at the bottom out of the data set. This behavior is kind of awkward.
Is my only choice do disable automatic revalidation completely? How would you handle this?

Gutenberg Block Rendering from JSON

I am trying to make custom Gutenberg Blocks through a plugin. Everything is going smooth the only issue is when I select my block from the blocks menu, it just pastes the JSON on the front. What I rather want is to render this JSON to make blocks.
I am fetching blocks' content from an API. I am attaching my code as well.
function makeBlock(block, category){
var jsonBlock = {
"__file": "wp_export",
"version": 2,
"content": ""}
;
$.ajax({
type: "POST",
url: document.location.origin+"/blocknets/wp-admin/admin-ajax.php",
data: {
'action': 'makeBlocks',
'id': block.id
},
dataType: "json",
encode: true,
}).done(function (resp) {
// console.log(resp);
jsonBlock.content = resp.data.content;
});
( function ( blocks, element, data, blockEditor ) {
var el = element.createElement,
registerBlockType = blocks.registerBlockType,
useSelect = data.useSelect,
useBlockProps = blockEditor.useBlockProps;
// debugger;
registerBlockType( 'custom-blocks/'+category+'-'+block.id, {
apiVersion: 2,
title: block.name,
icon: 'megaphone',
category: category,
edit: ()=>{return jsonBlock.content},
save: () => null
} );
} )(
window.wp.blocks,
window.wp.element,
window.wp.data,
window.wp.blockEditor
);
}
Purple Highlighted is my plugin, and Yellow is what it prints out.
What I rather want is to render this JSON. If I just paste this JSON into code editor it would look like this.
Can anyone help me out?
The jsonBlock.content displayed in the Editor view is serialized block content. The first step is to use parse() to transform the content into valid blocks. Next, to render the blocks I found RawHTML can be used to render innerHTML from the block content. The <RawHTML/> component uses dangerouslySetInnerHTML as seen commonly in React to render inner HTML content. Eg:
Edit()
const { parse } = wp.blockSerializationDefaultParser;
const { RawHTML } = wp.element;
export default function Edit({ attributes, setAttributes }) {
// Example of serialized block content to mimic resp.data.content data
var content = "<!-- wp:paragraph --><p>paragraph one</p><!-- /wp:paragraph --><!-- wp:paragraph --><p>then two</p><!-- /wp:paragraph -->";
// Parse the serialized content into valid blocks using parse from #wordpress/block-serialization-default-parser
var blocks = parse(content);
// Iterate over each block to render innerHTML within RawHTML that sets up dangerouslySetInnerHTML for you..
return blocks.map((block, index) => <RawHTML key={index}>{block.innerHTML}</RawHTML>);
}
Nb. The example covers parsing and displaying block content in the Editor, it does not cover saving the content, as your existing save() function is set to null.
I was able to render all the blocks by using the following edit function:
edit: ()=>{
window.wp.data.dispatch( 'core/block-editor' ).insertBlocks( window.wp.blocks.parse( jsonBlock.content));
return null;
}

next.js how to pass data to a page

Hi guys I'm learning some next.js and I'm trying to pass data from a data.js file to a page in the pages folder. I tried using getStaticProps but that needs an absolute URL. Below ill show an example of what I'm trying to do. Firstly is the page itself.
const page = ({ data }) => {
return (
<>
<p>{data.name}</p>
</>
);
};
export default page;
Then the data.js file looks like such.
export const user = [
{
id: 'Banana1',
password: 'Apple123',
name: 'Banana',
surname: 'Orange',
birthday: '10 March 2077',
cellNumber: '011 111 1111',
email: 'Banana#apple.com',
}
]
I know there is probably better methods of keeping the data but I'm just looking for something really simple for what I'm trying to do.
With help from #trash_dev I added the import { user } from '../path/to/datafile' in the page.js and also in the page.js removed the ({ data }) as that wasn't needed.
Then with help from #juliomalves when trying to use the data the array position had to be used so in my example it would be as follows:
const page = () => {
return (
<>
<p>{user[0].name}</p>
</>
);
};

WP API and JS : Cannot read property 'wp:featuredmedia' of undefined

I write a component to display a list WP posts on a page build with nuxt.js and I just can not display the featured image.
The Vue Component
<template>
<div class="references__grid">
<div class="references__item" v-for="item in references">
<h3><nuxt-link :to="slugToUrl(item.slug)"><h2 class="is-title">{{ item.title }}</h2></nuxt-link></h3>
<div v-html="item.excerpt"></div>
<div>{{ item.image }}</div>
<strong class="more"><nuxt-link :to="slugToUrl(item.slug)">Lire la suite</nuxt-link></strong>
</div>
</div>
</template>
The request
getReferences() {
return new Promise((resolve, reject) => {
request.defaults.baseURL = this.baseUrl;
request.get(`posts?categories=46&per_page=6&_embedded`).then(response => {
const data = [...response.data];
if (response.status === 200 && response.data.length > 0) {
const filtered = {
total: response.headers["x-wp-total"],
totalPages: response.headers["x-wp-totalpages"],
data: data.map(item => ({
id: item.id,
title: item.title.rendered,
content: item.content.rendered,
excerpt: item.excerpt.rendered,
slug: item.slug,
image: item._embedded["wp:featuredmedia"][0].media_details.sizes.full.source_url
}))
};
resolve(filtered);
} else {
reject(response);
}
});
});
},
The WP Api seems ok: https://www.agencedebord.com/wp-json/wp/v2/posts?categories=46&per_page=61&_embed
The error message:
ERROR
TypeError: Cannot read property '0' of undefined
server-bundle.js:1525 filtered.data.data.map.item
server-bundle.js:1525:56
Array.map
server-bundle.js:1519 >__WEBPACK_IMPORTED_MODULE_1_axios___default.a.get.then .response
server-bundle.js:1519:24
next_tick.js:160 process._tickCallback
internal/process/next_tick.js:160:7
So why item._embedded is undefined?
There is no problem for item.id or item.slug... any clarification is appreciated.
Finally, I did not use "_embed" but I add a new endpoint following this answer : Get Image URL instead of Attachment Id in Rest API
I think that the request url is not correct, you should use _embed not _embedded
So it will be request.get(posts?categories=46&per_page=6&_embed)
Otherwise, the _embedded part will be missing in the json response.
The problem is sometimes item._embedded['wp:featuredmedia'] is returning undefined, you can confirm you get that by console.log(item._embedded['wp:featuredmedia']), the solution for that by wrapping it in if condition, if it not undefined to proceed if(item._embedded['wp:featuredmedia']){ return let imageUrl = item._embedded["wp:featuredmedia"][0].media_details.sizes.full.source_url
} else { return null}
I had one post that was giving this error. I had the if/else setup properly but it was still erroring. I went to the problem post and resaved the featured image and also changed to the ajax to load .full.source_url instead of .medium.source_url and that fixed the error.
I imported some photos from another wordpress. some of them had not featured images yet they somehow acting like they have. (has_post_thumbnail() was acting same way and returns true for that posts)
My solution is checking if they 'really' have thumbnail:
if(post.featured_media == 0 || post._embedded['wp:featuredmedia'][0].media_details == undefined){
imageSource = null;
}
else{
imageSource = post._embedded['wp:featuredmedia'][0].media_details.sizes.full.source_url;
}

Pnotify and fullcalendar

I am using pnotify and loading callback function to show a notification when the fullcalendar plugin has loaded all events.
loading:function(isLoading, view){
if (isLoading === false){
new PNotify({
title:"Finished loading events",
type:'success',
delay: 1000
});
My problems is that when ever I move to different dates it calls loading again so I am left with so many notifications shown on my screen that it becomes very unusable. How can I bypass this? Is there a way to check if a notification is active and just change the text and title of it?
You can add that logic based on the template you're using (check the template docs).
Your code would be something like
loading:function(isLoading, view){
var exists = false;
$(".ui-pnotify-title").each(function() {
if ($(this).html() == 'Finished loading events')
exists = true;
});
if (!exists) {
new PNotify({
title:"Finished loading events",
type:'success',
delay: 1000
});
}
}
It would be better if you could use a specific id or class to detect if the notification is already shown, but this works.
Take a look at the working jsfiddle.
You can just store it in a variable, do your necessary code (like nullable/undefined checks, etc) and call "update()" (here: http://sciactive.com/pnotify/ - for example, find for 'Click Notice' and see the source)
var p = new PNotify({
title: 'Some title',
text: 'Check me out! I\'m a error.',
type: 'error',
icon: 'fa fa-times-circle'
});
// ... code ...
p.update({title: 'My new title'});

Resources