Headless WordPress + Sapper Comments on Posts (Part 2)
Tags: javascript, svelte, sapper, wordpress
Published: 2020-08-09 22:07:34

#### #1 fetching the comments

The `_embed` query gets comments, featured image and few other optional properties of the blog post

![Comments](https://dev-to-uploads.s3.amazonaws.com/i/mc3ujoaqmh4cw3nlxe8j.png)

```js
{#if post._embedded.replies}
     {#each post._embedded.replies[0] as comment}
	<div class="comment-item">
	  <div class="author-meta">
		<img src={comment.author_avatar_urls["96"]} alt={comment.author_name}>
		<span>{comment.author_name} <a href={comment.author_url}>{comment.author_url}</a></span>
	</div>
		{@html comment.content.rendered}
	 </div>
      {/each}
	{:else}
	<p>No commets yet :D but you could write one</p>
{/if}
```
Iterating `post._embedded.replies[0]`this should list out all the comments and it should be populated in the frontend

![Comments](https://dev-to-uploads.s3.amazonaws.com/i/0zlttofg8cuzdxcie5rc.png)


#### #2 Posting/Submitting comment from Sapper

**Sanity Check** before posting comments or you would get this particular error.

```json
{"code":"rest_comment_login_required","message":"Sorry, you must be logged in to comment.","data":{"status":401}}
```
To resolve this we need to modify `functions.php` located in your server at `/wp-content/themes/twentytwenty` twentytwenty is the theme I am using so if you are using some other theme then go to it's respective folder.

add this immediately after all the comments/meta
```php
add_filter( 'rest_allow_anonymous_comments', '__return_true' );
```
###### Snippet from [Cannot Comment Without Being Logged In #2960](https://github.com/WP-API/WP-API/issues/2960#issuecomment-266224756) 


#### #3 Testing with Postman

The comment API URL `https://your-domain/wp-json/wp/v2/comments`
needs a valid author_name, author_email, content (User comment), post (post id) without which you will face 4XX errors.

Since `export let post;` contains data of the post `post.id` from the current page will get you the id of the post, in my case it is 8

![Comment from Postman](https://dev-to-uploads.s3.amazonaws.com/i/vhkv1d70uagvm5q7q3tj.png)


#### #4 Posting via Sapper

Three input fields and a textarea to meet the API criteria for posting a comment.

```js

	let name, email, url, comment = ''

	let formerrors;
	let commentSuccess = false;
	async function handleSubmit(e) {


		let formdata = new FormData();
		formdata.append("author_name", name);
		formdata.append("author_email", email);
		formdata.append("author_url", url ? url : '');
		formdata.append("content", comment);
		formdata.append("post", post.id);

		let requestOptions = {
			method: 'POST',
			body: formdata,
		};

		fetch(`${process.env.SAPPER_APP_API_URL}/comments`, requestOptions)
			.then(response => response.json())
			.then(result => {
				console.log(result)
				if (result.code == "rest_comment_content_invalid") {
					formerrors = result.message;

				}
				if (result.code == "rest_invalid_param") {
					formerrors = result.data.params.author_email;
				} else {
					commentSuccess = true;
					name, email, url, comment = ''
				}
				return result;
			})
			.catch(error => console.log('error', error));
	}
```

Then the svelte part of the comment
```html
<form on:submit|preventDefault={handleSubmit}>
		<input class="form-input" type="text" name="name" placeholder="Name" required bind:value={name}> 
		<input class="form-input" type="email" name="email" placeholder="Email" required bind:value={email}>
		<input class="form-input" type="text" name="url" placeholder="Website" bind:value={url}>

		<textarea name="comment" cols="30" rows="10" bind:value={comment}></textarea>
		<button type="submit">Submit</button>
		{#if formerrors}
		<p class="errors">{formerrors}</p>
		{:else if commentSuccess} 
		<p class="success">Comment has been submitted and held for approval</p>
		{/if}
</form>
```

WordPress also returns validation errors on all input fields so you can handle them however you wish, the above example just shows the error.


Thank you for reading through the tutorial, Next part will cover fetching pages from WordPress.