Wordpress action hook on rest api update - angularjs

I made an app which uses Wordpress REST API to fetch data and users can manipulate the data and add their own posts from the app.
The app is written in AngularJS and uses http.post method to add a post and http.put to update the existing post. We are using custom posts which are made with Pods plugin.
I am trying to find an action hook which would fire whenever a user makes a http.post or http.put request to the REST API.
So far I tried:
function on_all_status_transitions( $new_status, $old_status, $post ) {
if ( $new_status != $old_status ) {
// A function to perform actions any time any post changes status.
}
}
add_action( 'transition_post_status', 'on_all_status_transitions', 10, 3 );
And also: add_action(save_post)
Thanks in advance!

Have you tried rest_post_dispatch Hook?
Allows modification of the response before returning:
https://developer.wordpress.org/reference/hooks/rest_post_dispatch/

I solved the problem
Turns out the folder where I should save JSON file was not set correctly which caused an error. I checked the error log and that is where I saw what the problem is.
After setting the path to folder correctly the function triggered with action hook worked.
This is the hook I use to trigger the function when the post is updated or a new post is added from the app using http.post or http.put methods:
add_action('pods_api_post_save_pod_item_your_pod_name', 'your_function', 10, 3);
I am using Pods plugin for custom post and this is the action hook from their documentation.

Related

Using XMLHttpRequest to send a Mailchimp API request in my React Typescript App so users subscribe to the newsletter

I want to use Mailchimp API in my website so users can enter their email in a field and subscribe to a newsletter. I do not want to use any libraries.
I created a simple form for now with an email field and subscribe button for testing purposes and tried to achieve my goal with XMLHttpRequest. However it does not work, and I am not sure whats wrong or if I need another approach? Is my code structure for the API request correct?
I created a Codesandbox with the code.
If needed I can paste it also here.
It's a back end only API.
You're not supposed to ship this API key with your JavaScript application. It's intended for back end use only, where you can keep the key private.
Probably the issue described in no more detail than "it does not work", is because Mailchimp will block the request if you try to use the key from a browser. Their documentation describes in detail.
Because of the potential security risks associated with exposing account API keys, Mailchimp does not support client-side implementation of our API using CORS requests or including API keys in mobile apps.
If you still want to use the API for this, you'll have to set up your own back end service which receives the data from the front end of your site and forwards it to Mailchimp.
For example, if your website uses PHP, you could preserve your form's JS code, but point it to your own custom endpoint / PHP file instead.
Mailchimp has a PHP client library you could use to make crafting the HTTP request more robust and less verbose. But you could also do it "manually" if you also don't want to install a PHP library.
// form-submission.php
function read_key() {
// Could also come from other source, like environment variables.
// As long as it's in a safe place and can't be leaked.
return file_get_contents(SECRET_KEY_LOCATION);
}
$apiKey = read_key();
require_once('/path/to/MailchimpMarketing/vendor/autoload.php');
$mailchimp = new MailchimpMarketing\ApiClient();
$mailchimp->setConfig([
'apiKey' => $api_key,
'server' => 'YOUR_SERVER_PREFIX'
]);
$response = $mailchimp->lists->addListMember( /* ... form data */);
print_r($response);
Depending on your use case you may need to use one of the many other API endpoints.
The issue is the onSubmit() callback on your "form" element is never executed. In order for the onSubmit() callback on your form to be called upon clicking the "Subscribe" button, the button needs to have a type="submit" attribute on it.
i.e.,
const handleSubmit = () => { ... }
return (
...
<Box
onSubmit={handleSubmit}
>
<TextField ... />
<Button
type="submit" <-- Add this in order to call onSubmit() upon click
>
Subscribe
</Button>
</Box>
...
Edit:
OP is using the MailChimp API from the client. The MailChimp API will not work on the client side. You can only use the MailChimp API on the server side.
However, you can utilize MailChimp's embedded form action URL to subscribe to user's emails on the client side (in a React component). You can avoid the user from being forwarded to MailChimp by sending a fetch POST request with the embedded form action URL.
This below example may need some tweaking, but this is the general idea on how this can be accomplished.
function handleSubmit(event) {
event.preventDefault();
// fetch URL is from MailChimp embedded form action url.
fetch('http://mailchimp.us8.list-manage.com/subscribe/post', {
method: 'POST',
// Not sure if MailChimp used urlencoded or json. You can modify this request to use either.
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'u': 'a123cd45678ef90g7h1j7k9lm', <-- found in embedded form code.
'id': 'ab2c468d10', <-- found in embedded form code.
'MERGE0': email, <-- email to be subscribed.
})
});
}

How to Access Data in Redux Store?

I am building an application and am trying to show article content from mongoDB using axios, node.js, and express on a React frontend. I can pull the data to my redux store but when I try to display it I get a cannot read property 'author' (or whatever property in the state I'm going for) of undefined error.
Here are some screenshots of my react file, as well as the action and reducer. Let me know what other info you might need. Thanks a ton.Here is my React file. Here is the action. here is my reducer.
Because the initial of state is empty object {}. So while fetching API, state.articles is undefined and this issue occur.
You can fix by add condition before using with optional chaining
const articles = useSelector((state => state.articles);
const current = articles?.current ;

MERN - Connect Front and Back End

I am new on web development.. Sorry if the question sounds stupid or if I had mess up with my code.
I have this problem: I've tried to create a simple "To Do List" application using MERN stack.
I did connect React with the backend: I can send get and post request and they are working (i'm adding items to my mongoDB).
Here comes the issue: I cannot delete item from my list. The delete request is not working because I'm not able to get my item ID in react and honestly I don't know why.
Here it is my react code:
code
The problem should be that I'm not getting the ID of my data... But I don't know how to fix it
the problem is that instead of passing the id to deleteNow function, you are passing the parameters from the onPress event.
So, if you want to make it work, do this change:
change:
onPress={deleteNow} to onPress={() => deleteNow(data._id)}
Update onPress={() => deleteNow(data._id)} . if you not did that in SingleItem component
I am adding one more point.
your code
In addNote function -
1.update the state data with newItem received in the function.
2.then updated the Db.
now, the problem is the newItem added to data state won't have _id property because it is not from db.
my suggestion
1. post your data as you did with axios.
2. received the newly added db document via response and add to data state.

Communication Between Component and API using Redux- Saga

How can we get the data from the saga directly into our component ?
or
Is this a pattern we should not follow and directly make a service/ api
call from the component using some service layer.
I have been following this issue on git on if this is possible there are too many permutations and combinations and i am a bit confused ..
I tried this small example by refering this
stackblitz.
In this case when i try and return this
function* helloSaga() {
return new Promise(function(resolve, reject) {
resolve('start of new Promise');
});
}
and access it like this
let response = dispatch(action('SHOW')).then(data => {
console.log(data); // i cannot get this to work say if this were a api response .
})
Nothing happens .
Is this pattern acceptable if yes then how can we make it work and what am i missing it
And if this pattern is an anti-pattern then making service calls from a layer like getData() should be enough from componentDidMount() .
A generator function doesn't really return a value (or the promise in your case) as you'd expect with any "regular" function. It returns a generator-object that you can pause, continue, cancel etc.
Check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
The way to go with redux-saga in a web app would be:
Trigger an action like "SHOW" in your example
Have a saga take your action "SHOW"
The saga would then do the async API request
Once the API request is done, the saga dispatches another action (something like FETCH_SUCCEEDED
Handle the action in your reducer and store the response in the redux store.
Once it's stored in the redux store, you can select it from any react component you want to (use connect from redux for that)
Here's your stackblitz with a minimal example:
https://stackblitz.com/edit/react-redux-sagas-demo-app-4tpevb?file=index.js
For a production app, you'd want to wrap the API request in a try{..}catch(){..} and handle the error with a proper action like FETCH_FAILED and display an error message in your FE (if it effects the user).

Server-side rendering for a specific selection

Let's say my app is a list of many items. There's a lot of items so I don't want to include all the items in the redux state.
When a user visits me at myapp.com/item/:itemId, I want to display the selected item. Currently I make an api call in componentDidMount to fetch the item and store the response in myReduxState.selectedItem. However, this shows the user and unfinished page until the api call finishes.
Is there any way I can get around this?
The pattern I tend to follow is to have a state of fetching being tracked in the redux state. Once the api resolves you just make sure the state is set correctly and then in your render methods use that to determine what you are rendering.
render() {
if (this.state.fetching) {
return <div> // put whatever you want here, maybe a loading component?</div>
}
return (
// put the regular content you would put for when the api call finishes and have the data you need
)
}
I solved this problem by making the creating the state on the server side. I get the itemId from the url in my express route and get the details of the specific item. I use this to create the state and pass it to the front-end.

Resources