React, Axios and Rest API - filter ACF fields - wordpress

I am trying to filter my axios request to only get the item if the yarn_stock is greater than 2.
I am currently getting the full list of yarns using /wp-json/wp/v2/yarn
The yarn in this case is a custom Taxonomy Term created under Products in Woocommerce that I created using the CPT plugin and
the yarn fields are Advanced Custom Fields
i can scope the acf fields for example to only get the acf field yarn_stock using this url:
mydomain.com/wp-json/wp/v2/yarn?_fields=acf.yarn_stock
which results in this json being returned:
{
"acf": {
"yarn_stock": 1
}
},
{
"acf": {
"yarn_stock": 0
}
},
{
"acf": {
"yarn_stock": 4
}
},
// etc
my axios request is as follows:
const { parent } = req?.query ?? {};
// create a query parameter e.g. api/get-products?perPage=2
const { perPage } = req?.query ?? {};
try {
const { data } = await api.get("yarn", {
parent: parent || 227,
per_page: perPage || 100,
// want to add a parameter here to filter the acf.yarn_stock > 2
});
the api results are:
[
{
"id": 263,
"count": 0,
"description": "",
"name": "Amber",
"slug": "amber",
"taxonomy": "yarn",
"parent": 251,
"meta": [],
"acf": {
"yarn_image": "",
"yarn_color": "#f7c26c",
"yarn_brand": "Debbie Bliss Rialto 4 Ply",
"yarn_price": 7,
"yarn_fiber": [],
"yarn_benefits": false,
"yarn_stock": 1
}
},
{
"id": 252,
"count": 0,
"description": "",
"name": "Brick Red",
"slug": "brick-red",
"taxonomy": "yarn",
"parent": 227,
"meta": [],
"acf": {
"yarn_image": "",
"yarn_color": "#711d2a",
"yarn_brand": "Rico Essentials Merino DK",
"yarn_price": 6.5,
"yarn_fiber": [254],
"yarn_benefits": [300, 299, 305, 303],
"yarn_stock": 4
}
}
]
i would like to add another parameter to my axios request to only pull items that have yarn_stock greater than 2
would be grateful for any ideas, tearing my hair out!
i tried adding a filter to wordpress functions.php as a solution i saw on stackoverflow which was to add a filter at that side but it doesnt work for me.
i read ACF documentation but cant make sense of it for my situation
my expected result is to have all of the data returned for items that have a yarn_stock greater than 2. for example i should see all fields for Brick Red yarn as it has a yarn stock of more than 2 and i should not be shown the Amber yarn with a yarn_stock of less than 2

Related

Data Grid - Remote Grouping - .NET Controller with Angular - Custom Store

I am trying to implement a Devextreme Data Grid with Remote Grouping with a Custom Store using .NET MVC, Angular. The configuration of my custom store looks like this:
this.dataSource = new CustomStore({
key:"id",
load: (loadOptions: any) => {
const gridHeaderModel: overviewGridModel = {
skip: loadOptions.skip || 0,
take: loadOptions.take || 20,
sortDescending: loadOptions?.sort?.[0]?.desc ?? true,
sortBy: loadOptions?.sort?.[0]?.selector ?? null,
filters: new OverviewFilterGridModel()
};
return this.service.getData(gridHeaderModel);
}
});
The data that is returned is in the following format:
"data": [
{
"id": 1,
"employeeId": 11
},
{
"id": 2,
"employeeId": 22
}
],
"totalCount": 2
Here is the implementation of the grid:
<dx-data-grid
#exampleGrid
[dataSource]="dataSource"
[allowColumnResizing]="true"
[columns]="columns"
[showRowLines]="true"
[showColumnLines]="true"
[showBorders]="true"
[remoteOperations]="{ groupPaging: true }"
>
<dxo-scrolling mode="virtual"></dxo-scrolling>
<dxo-group-panel [visible]="false"></dxo-group-panel>
<dxo-grouping [autoExpandAll]="true"></dxo-grouping>
<dxo-filter-row [visible]="true" [showOperationChooser]="false"></dxo-filter-row>
</dx-data-grid>
I am getting this error after loading of the grid:
E1037 - Invalid structure of grouped data. See: http://js.devexpress.com/error/21_1/E1037
Every example that i found out on the documentations and Support Center Q&A section was with using Web API Service which is not suitable for my problem. Also when i was analyzing the example here https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/RemoteGrouping/Angular/Light/ i saw that the FE fires 3 different calls when i scroll on the grid. Why? Also i searched all Support Center but i wasn't able to find answers about my problem.
Can you help me about my problem? Can you share with me example of implementation of data grid with grouping with above technologies?
Thank you!
The problem with the above example was the model that was returned from the server.
Solution is to change the model like this:
{
"data": [
{
"key": "Blagojche",
"items": [
{
"id": 1038,
"employeeId": 52,
"employeName": "Blagojche"
}
]
},
{
"key": "Peter",
"items": [
{
"id": 1025,
"employeeId": 53,
"employeName": "Peter"
}
]
}
],
"totalCount": 38
}

how to filter only one data with a specific slug in sanity.io?

Data:
[
{
"name": "Gates of Olympus",
"slug": {
"_type": "slug",
"current": "gates-of-olympus"
}
},
{
"name": "Floating Dragon",
"slug": {
"_type": "slug",
"current": "floating-dragon"
}
},
{
"name": "Buffalo King Megaways",
"slug": {
"_type": "slug",
"current": "buffalo-king-megaways"
}
},
{
"name": "Fruit Party",
"slug": {
"_type": "slug",
"current": "fruit-party"
}
}
]
How do I query only objects with slug gates-of-olympus ?
Code:
export const getServerSideProps = async ({params}:any) => {
const query = `*[_type=="game"]{
name,
slug,
}`;
const games = await sanityClient.fetch(query);
return {
props: {
games,
},
};
};
slug is obtained through context (params.game).
I also tried,
*[_type=="game" && slug.current == ${params.game}] but still returns all data.
Wrap ${params.game} with the quotes. Like this "${params.game}". It will work
You get back all the data but the first one or first item in that array of data is the one your searching for so at the end of your query put [0] at the end to get the first value you should be solid eg *[_type=="game" && slug.current == '${params.game}'][0]
Ref
go to this video which is taught by js mastery skip to 1:21:27 he starts explaining how to get the current slug/product https://www.youtube.com/watch?v=4mOkFXyxfsU&t=5153s

Using Gatsby `createResolvers` to set default image if GraphQL returns null?

I'm working on a gatsby site using gatsby-source-wordpress to source posts for the blog. However, if any of the WordPress posts do not include a featured image this causes the build to fail. I understand that this is expected behavior.
Here is the build error I am seeing:
29 | {posts.map(({ node: post }, index) => (
30 | <li key={post.id} {...post}>
> 31 | <Img fixed={post.featured_media.localFile.childImageSharp.fixed} />
| ^
32 | <p>
33 | <Link to={`/insights/${post.slug}`}>
34 | {post.title}
WebpackError: TypeError: Cannot read property 'localFile' of null
This is caused by the resulting query, which is returning a null result in the second node because there is no featured image on the post:
{
"data": {
"allWordpressPost": {
"edges": [
{
"node": {
"id": "28ec9054-5b05-5f94-adcb-dcbfc14659b1",
"featured_media": {
"id": "f12d613b-e544-560b-a86f-cd0a7f87801e",
"localFile": {
"id": "7fca2893-ff80-5270-9765-d17d3dc21ac2",
"url": "https://www.mycustomdomain.com/wp-content/uploads/2020/01/some-featured-image.jpg"
}
}
}
},
{
"node": {
"id": "91a236ed-39d5-5efc-8bed-290d8344b660",
"featured_media": null
}
}
]
}
}
}
How I would like to fix:
As an ideal solution, I would like to use schema customization to set a default image if there is no featured image in WordPress. But I am at a total loss how to correctly do so. I am working from this documentation to guide me, but I'm just not getting my head wrapped around it properly.
A similar working example:
Tag data is similar to featured images in that the query returns null if the post has no tags. However I am able to set a default undefined tag using createResolvers like so:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
wordpress__POST: {
tags: {
resolve(source, args, context, info) {
const { tags } = source
if (tags === null || (Array.isArray(tags) && !tags.length)) {
return [
{
id: 'undefined',
name: 'undefined',
slug: 'undefined',
}
]
} else {
return info.originalResolver(source, args, context, info)
}
},
},
},
}
createResolvers(resolvers)
}
And this works as shown in the following query results:
{
"data": {
"allWordpressPost": {
"edges": [
{
"node": {
"id": "28ec9054-5b05-5f94-adcb-dcbfc14659b1",
"tags": [
{
"id": "undefined"
}
]
}
},
{
"node": {
"id": "91a236ed-39d5-5efc-8bed-290d8344b660",
"tags": [
{
"id": "50449e18-bef7-566a-a3eb-9f7990084afb"
},
{
"id": "8635ff58-2997-510a-9eea-fe2b88f30781"
},
{
"id": "97029bee-4dec-5198-95af-8464393f71e3"
}
]
}
}
]
}
}
}
What I tried for images (isn't working...)
When it comes to nested nodes and image files I'm at a total loss. I am heading in the following direction based on this article and this code example, but so far it isn't working:
exports.createResolvers = ({
actions,
cache,
createNodeId,
createResolvers,
store,
reporter,
}) => {
const { createNode } = actions
const resolvers = {
wordpress__POST: {
featured_media: {
type: `File`,
resolve(source, args, context, info) {
return createRemoteFileNode({
url: 'https://www.mycustomdomain.com/wp-content/uploads/2017/05/placeholder.png',
store,
cache,
createNode,
createNodeId,
reporter,
})
},
},
},
}
createResolvers(resolvers)
}
I realize the above code does not have an if else statement, so the expectation is that all featured images would be replaced by the placeholder image. However the resulting GraphQL query is unaffected (as shown at top).
Can anyone point me in the right direction here? I can't seem to wrap my head around what information I can find out there.
WebpackError: TypeError: Cannot read property 'localFile' of null
'localFile' of null means that nulled is a parent of localfile - featured_media ... you can see that in results:
"featured_media": null
... so you're trying to fix localfile while you should work on featured_media level
why?
You can easily render conditionally [in react] what you need (placeholde, component) on nulled nodes ... why at all you're trying to fix graphql response?

React/redux : this.props returns undefined value + array

I am using React/redux to build my app.
Here is my data (json)
{
"categories": [
{
"id": 1,
"name": "category 1",
"slug": "category-1"
"content": [
{
"id": 1,
"title": "title 1 "
},
{
"id": 2,
"title": "title 2 "
}
]
}
]
}
what I want to do :
select a category
display the content of the category selected
my store is like that :
categoryItems: [], // list of categories
categorySelected: []
data is saved correctly on my state when I select a category
on Category component I implement the function selectCategory which calls the action SELECT_CATEGORY and dispatch data to reducer. so far so good!
getCategoryList() {
return this.props.categories.map((category) => {
return (<li key={category.id}>
<Link to={`/category/${category.slug}`} onClick={() =>this.props.selectCategory(category.slug)} >{category.name} </Link>)});}
and on CategoryDetail, when I console.log(this.props.categorySelected.name) I got:
undefined
name
here is the problem because I can not read this.props.categorySelected.name
How to fix this and read proprely this props?
You have to give the complete object to your selectCategory() function.
Like this:
getCategoryList() {
return this.props.categories.map((category) => {
return (<li key={category.id}>
<Link to={`/category/${category.slug}`} onClick={() =>this.props.selectCategory(category)} >{category.name} </Link>)});
}

Redux state shape without data duplication

I'm new to redux and it's hard to grasp how to implement good state shape without duplicating data, in case I need to update it, and naive way would be to update in few places, but that would negate the single source of truth.
We fetch user profile and posts from API server:
www.api.com/users/placeholder
{
"user": {
"username": "placeholder",
"bio": "It's my bio",
"profileImage": "http://via.placeholder.com/350x150",
"isViewerFollowing": false
}
}
www.api.com/posts?author=placeholder
{
"posts":[{
"id": "1",
"caption":"caption placeholder",
"image":"http://via.placeholder.com/1000x1000",
"createdAt": "2017-08-18T03:22:56.637Z",
"updatedAt": "2016-08-18T03:48:35.824Z",
"isLikedbyViewer": false,
"likesCount": 0,
"author": {
"username": "placeholder",
"bio": "It's my bio",
"profileImage": "http://via.placeholder.com/350x150",
"isViewerFollowing": false,
}
},
{
"id": "2",
"caption":"caption placeholder",
"image":"http://via.placeholder.com/1000x1000",
"createdAt": "2017-08-18T03:22:56.637Z",
"updatedAt": "2016-08-18T03:48:35.824Z",
"isViewerLiked": false,
"likesCount": 0,
"author": {
"username": "placeholder",
"bio": "It's my bio",
"profileImage": "http://via.placeholder.com/350x150",
"isViewerFollowing": false,
}
}],
"postsCount": 2
}
For example, we have separate reducers for users and posts, and user wants to follow user/author, then we would need to update information in two reducers. So my final question would be, could someone hint me what would good state shape look like in this particular example ?
Thanks!
You should normalize your Redux state: instead of saving the entire author object for every post, you should just save the authorId.
Since you ensure that when you have a post object in the posts branch of your Redux state, you also have the related author in the authors branch, to retrieve all the posts with their author's data you can create a selector:
export function getPosts(reduxState) {
return reduxState.posts.map(post => {
const author = reduxState.authors.find(a => a.id === post.authorId);
return {
...post,
author
};
});
}

Resources