i create comment in WordPress with REST API. But can't set comment meta. I don't know why, maybe i missing a little bit. So please help.
The code:
// Data
var ajax_data = {
author: user.user_id,
author_email: user.user_email,
content: comment,
parent: parent,
post: post_id,
meta: {
'_crating_speed': rating_speed,
'_crating_price': rating_price,
},
}
// Set header
$.ajaxSetup({
headers: {
'Authorization': "Bearer " + user.token,
}
});
// AJAX
$.post( rest_base + '/comments', ajax_data ).done( function( response ) {
console.log(response);
}).fail( function( xhr, status, error ) {
console.log( error);
}, 'json' );
The meta _crating_speed and _crating_price not inserted to database.
Same issue, solution is to add these using register_meta() which will add the meta fields to the schema of the comment.
https://developer.wordpress.org/reference/functions/register_meta/
In my case the following worked:
add_action('init', function() {
register_meta('comment', 'stars', [
'type' => 'number',
'description' => __('Stars'),
'single' => true,
'show_in_rest' => true
]);
}, 10 , 0);
Related
I'm working on building a Gutenberg block but it seems I keep getting an infinite loop. How can I invoke the rest API only once?
I am trying to get a list of officers - custom post type - but as the initial call doesn't provide the featured image I thought I should loop through and add the images "manually". If there is a better approach please do let me know.
registerBlockType('test/officers-block', {
title: __('Officers Block', 'test'),
description: __('Block to generate the officers block', 'test'),
icon: '',
category: 'test',
attributes: {
title: {
type: 'string',
},
posts: {
type: 'array',
}
},
edit: ({ attributes, setAttributes }) => {
const {
title,
posts,
} = attributes
// Request data
const data = useSelect((select) => {
return select('core').getEntityRecords('postType', 'officers', { per_page: -1 });
});
const isLoading = useSelect((select) => {
return select('core/data').isResolving('core', 'getEntityRecords', [
'postType', 'officers',
]);
});
const setOfficers = ( data ) => {
let officerData = [];
data.map(( officer ) => {
wp.apiFetch( { path: '/wp/v2/media/' + officer?.featured_media } ).then( function( image ){
officerDataEach.title = officer?.title?.rendered
officerDataEach.content = officer?.content?.rendered
officerDataEach.job = officer?.meta?._job_title
officerDataEach.phone = officer?.meta?._phone
officerDataEach.email = officer?.meta?._email
officerDataEach.image = image?.media_details?.sizes?.full?.source_url
officerData.push( officerDataEach )
})
})
console.log(officerData);
setAttributes( { posts: officerData } )
}
if( !isLoading && data ){
setOfficers( data );
}
if ( isLoading && !data ) {
return <h3>Loading...</h3>;
}
...
Thanks in advance
I want to show list product from api but it shows the error:
Uncaught (in promise) TypeError: Cannot read property 'id' of null
at eval (Home.vue?bb51:103)
at renderList (runtime-core.esm-bundler.js?5c40:6635)
at Proxy.render (Home.vue?bb51:2)
at renderComponentRoot (runtime-core.esm-bundler.js?5c40:1166)
at componentEffect (runtime-core.esm-bundler.js?5c40:5265)......
my product like :
[
{
"id": 1,
"name": "chair",
"categoryId": 12,
"unitId": 2,
"price": 66000000,
"salePrice": 0,
"material": "wood",
"size": "x"
},
]
My code here:
Home.vue file
<ProductCard v-for="product in products" :key="product.id" :product="product" />
ProductCard.vue file
<script>
export default {
name: "ProductCard",
props: {
product: {
type: Object,
required: true,
},
},
};
</script>
ProductService.js file
const apiClient = axios.create({
baseURL: 'http://localhost:8888/api/v1',
withCredentials: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
export default {
getProducts() {
return apiClient.get('/product/get-list-product-by-subcategory')
},
}
When I print out list product in console. It still work.
Does anyone know where is the bug in my code?
Updated:
I try to fix my bug "Cannot read property 'id' of null", Steve's answer although remove my red warning in devtool but not deal my data: my data still not showing up. And I find out my code work by using this.products = response.data.data
ProductService.getProducts()
.then((response) => (this.products = response.data.data))
.catch((error) => console.log("error: " + error));
Explain by myself is:
When console.log(this.products = response)
And I need to use this.products = response.data.data to enter to array
apiClient.get(...)
returns a promise not the actual data from the API call.
You need to add a then. like so
apiClient.get(...).then(response => (this.products = response))
Then when the apiClient.get completes this.products will be populated with the data from the API.
Try this
<ProductCard v-for="product in products" :key="product._id" :product="product" />
I try to add a custom user field to the user by using WPGraphQL. Therefore I tried to recreate the example in the official WPGraphQL documentation https://docs.wpgraphql.com/extending/fields/#register-fields-to-the-schema :
add_action('graphql_init', function () {
$hobbies = [
'type' => ['list_of' => 'String'],
'description' => __('Custom field for user mutations', 'your-textdomain'),
'resolve' => function ($user) {
$hobbies = get_user_meta($user->userId, 'hobbies', true);
return !empty($hobbies) ? $hobbies : [];
},
];
register_graphql_field('User', 'hobbies', $hobbies);
register_graphql_field('CreateUserInput', 'hobbies', $hobbies);
register_graphql_field('UpdateUserInput', 'hobbies', $hobbies);
});
I already changed the type from \WPGraphQL\Types::list_of( \WPGraphQL\Types::string() ) to ['list_of' => 'String'].
If I now execute the updateUser mutation my hobbies don't get updated. What am I dowing wrong?
Mutation:
mutation MyMutation {
__typename
updateUser(input: {clientMutationId: "tempId", id: "dXNlcjox", hobbies: ["football", "gaming"]}) {
clientMutationId
user {
hobbies
}
}
}
Output:
{
"data": {
"__typename": "RootMutation",
"updateUser": {
"clientMutationId": "tempId",
"user": {
"hobbies": []
}
}
}
}
Thanks to xadm, the only thing I forgot was to really mutate the field. I was a bit confused by the documentation, my fault. (I really am new to WPGraphQL btw)
Here's what has to be added:
add_action('graphql_user_object_mutation_update_additional_data', 'graphql_register_user_mutation', 10, 5);
function graphql_register_user_mutation($user_id, $input, $mutation_name, $context, $info)
{
if (isset($input['hobbies'])) {
// Consider other sanitization if necessary and validation such as which
// user role/capability should be able to insert this value, etc.
update_user_meta($user_id, 'hobbies', $input['hobbies']);
}
}
My components.ts is,
getHomePageData() : void{
this.homeservice.getHomePageData()
.subscribe(
data => {
//console.log("response status ################### "+data.status);
//console.log("getUserData response ************ \n"+JSON.stringify(data));
this.defaultFacilityId = data.response.defaultFacilityId;
this.defaultFacilityName = data.response.defaultFacilityName;
this.enterpriseId = data.response.enterpriseId;
this.enterpriseName = data.response.enterpriseName;
this.facilityList = data.response.facilityList;
this.userName = data.response.userName;
this.showDefaultPopoup();
},
error => {
console.error(error);
//this.errorMessage="Technical error - Contact Support team !" ;
}
);
}
So my component.spec.ts is ,
it('getHomePageData with SUCCESS - getHomePageData()', () => {
backend.connections.subscribe((connection: MockConnection) => {
//expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
let options = new ResponseOptions({
body:
{
"request": { "url": "/getUserData" },
"response": {
"defaultFacilityName":"3M Health Information Systems",
"enterpriseId":"11.0",
"enterpriseName":"HSA Enterprise",
"defaultFacilityId": "55303.0",
"userName":"Anand"
},
"error": ""
},
status : 200
});
connection.mockRespond(new Response(options));
});
backend.connections.subscribe((data) => {
//expect(data.response.facilityId).toEqual("55303.0");
//expect(subject.handleError).toHaveBeenCalled();
})
service.getHomePageData().subscribe((data) => {
//expect(videos.length).toBe(4);
expect(data.response.defaultFacilityId).toEqual("55303.0");
component.defaultFacilityId = data.response.defaultFacilityId;
component.defaultFacilityName = data.response.defaultFacilityName;
component.enterpriseId = data.response.enterpriseId;
component.enterpriseName = data.response.enterpriseName;
component.userName = data.response.userName;
console.log("$$$$$$$$$$$$$$$$**********$$$$$$$$$$$$$$$$$$$$$");
});
});
When i try to run test case. It got passed. But while I look into the code coverage, it doesn't cover the code shown in red below
Please help to get the full code coverage. Thanks.
In the test you've shown here you don't seem to be calling getHomePageData() from your component
Try building your test like this:
import { fakeAsync, tick } from '#angular/core/testing';
...
it('getHomePageData with SUCCESS - getHomePageData()', fakeAsync(() => {
backend.connections.subscribe((connection: MockConnection) => {
//expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
let options = new ResponseOptions({
body:
{
"request": { "url": "/getUserData" },
"response": {
"defaultFacilityName":"3M Health Information Systems",
"enterpriseId":"11.0",
"enterpriseName":"HSA Enterprise",
"defaultFacilityId": "55303.0",
"userName":"Anand"
},
"error": ""
},
status : 200
});
connection.mockRespond(new Response(options));
});
// If this function is not automatically called in the component initialisation
component.getHomePageData();
tick();
//you can call expects on your component's properties now
expect(component.defaultFacilityId).toEqual("55303.0");
});
FakeAsync allows you to write tests in a more linear style so you no longer have to subscribe to the service function to write your expectations.
In a FakeAsync test function you can call tick() after a call where an asynchronous operation takes place to simulate a passage of time and then continue with the flow of your code.
You can read more about this here: https://angular.io/docs/ts/latest/testing/#!#fake-async
EDIT - Error Case
To test the error logic you can call mockError or set up an error response using mockRespond on your connection:
it('getHomePageData with ERROR- getHomePageData()', fakeAsync(() => {
backend.connections.subscribe((connection: MockConnection) => {
if (connection.request.url === 'http://192.168.61.158:9080/GetUserData') {
// mockError option
connection.mockError(new Error('Some error'));
// mockRespond option
connection.mockRespond(new Response(new ResponseOptions({
status: 404,
statusText: 'URL not Found',
})));
}
component.getHomePageData();
tick();
//you can call expects now
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
expect('you can test your error logic here');
});
What we're doing inside the subscription is making sure that anytime the GetUserData endpoint is called within this test method it will return an error.
Because we test errors and successes separately in the success test there's no need to add the error related settings in the request options.
Are you using JSON data? Then you should probably use map() before using .subscribe().
.map((res:Response) => res.json())
Try organizing your code like this:
ngOnInit() {
this.getHomePageData();
}
getHomePageData() {
this.http.get('your.json')
.map((res:Response) => res.json())
.subscribe(
data => {
this.YourData = data
},
err => console.error(err),
() => console.log('ok')
);
}
Hope it helps,
Cheers
I am looking for a way to retrieve all validation errors. (I'm using Collection2 and SimpleSchema)
Consider this code:
Foo.insert({
title: '',
description: ''
}, function(error, result) {
console.error(error);
});
output:
{
message: 'Title may not be empty.',
invalidKeys: [
0: {
name: 'title',
type: 'required',
value: ''
},
1: {
name: 'description',
type: 'required',
value: ''
}
]
}
I would like to have all the error messages that are related to validation.
Unfortunately I couldn't find any solution for this.
SOLUTION:
I've found a satisfiable solution
Foo.simpleSchema().namedContext().keyErrorMessage('title');
I ran into the same problem and my solution was to insert said errors into a client mongo error collection which would then display the errors to the user. The following is what I came up with:
Schema
Schema.newUser = new SimpleSchema({....});
Client Side Validation
function tokenRegistration (newUser) {
var valContext = Schema.newUser.namedContext('tokenRegForm');
if (!valContext.validate(newUser)) {
var keys = valContext.invalidKeys();
_.each(keys, function (value) {
var error = value.name,
message = valContext.keyErrorMessage(error);
return ErrorMessage.insert({errormessage: message})
});
}
}