Getting Started with Kuzzle and VueJS #
This section deals with Kuzzle (+ Javascript SDK) and VueJS. We will create documents in Kuzzle and subscribe to document notifications to develop a realtime chat.
Requirements #
- Node.js >= 8.0.0 (install here)
- Vue CLI (install here)
- Running Kuzzle Stack (instructions here)
Prepare your environment #
Create your VueJS app with Vue CLI. You'll need to select manually the features, just add Babel, Linter and select the default options for the other features.
vue create kuzzle-playground
Install Kuzzle's Javascript SDK:
cd kuzzle-playground
npm install kuzzle-sdk
In the App.vue file, you should remove the tag, the import and the component registration of the HelloWorld
component, we won't use it.
Instantiating Kuzzle SDK #
We have to connect the server so that our client can interact with it.
To do this, we have to create a src/services/kuzzle.js file to put our kuzzle instance declaration:
import { Kuzzle, WebSocket } from 'kuzzle-sdk';
export default new Kuzzle(new WebSocket('localhost'));
We need to import our Kuzzle SDK instance, so just add the following line in your <script>
tag in the App.vue file:
import kuzzle from "./services/kuzzle";
Then we will establish the connection to kuzzle and create, if they don't exist, the index and collection of our chat. Add the following valid()
method in the export of the <script>
tag of your App.vue file:
async valid() {
// Etablish the connection
await kuzzle.connect();
// Check if 'chat' index exists
if (! await kuzzle.index.exists("chat")) {
// If not, create 'chat' index and 'messages' collection
await kuzzle.index.create("chat");
await kuzzle.collection.create("chat", "messages");
}
await this.fetchMessages();
await this.subscribeMessages();
this.validate = true;
}
Get the username #
First of all, we need to know the user's name. Let's start by adding the following HTML code in the <template>
tag, allowing one to enter their name:
<div v-if="!validate">
<input
autofocus
v-on:keyup.enter="valid"
type="text"
v-model="username"
placeholder="Enter your nickname"
/>
<button @click="valid">Valid</button>
</div>
As you can see we'll need two properties: username
and validate
.
Display the messages #
We'll need some properties to manage our messages. Add the following data
to your App.vue
data() {
return {
message: "", // String containing the user input
messages: [], // Array containing our messages
roomID: "", // Id of the realtime subscription
username: "", // Nickname of the current user
validate: false // Value that will change the display (false => Pseudo input; true => Message input)
};
},
Then, create the following functions to fetch and display the messages:
// This function return the right formated date depending on the timestamp
getDate(timestamp) {
const date = new Date(timestamp);
return date.toLocaleString().split("GMT")[0];
},
// This function will create a message object containing the informations we need to display it
getMessage(document) {
const message = {
// The unique id of the document containing the message
_id: document._id,
// The text of the message
value: document._source.value,
// The creation date
createdAt: document._source._kuzzle_info.createdAt,
// The author name
username: document._source.username
};
return message;
},
The function fetchMessage()
will search for the first hundred newest messages and store them in our array, before subscribing to changes in the messages
collection. We called it in the valid()
function we created above.
async fetchMessages() {
// Call the search method of the document controller
const results = await kuzzle.document.search(
"chat", // Name of the index
"messages", // Name of the collection
{ sort: ["_kuzzle_info.createdAt"] }, // Query => Sort the messages by creation date
{ size: 100 } // Options => get a maximum of 100 messages
);
// Add each message to our array
results.hits.map(hit => {
this.messages = [this.getMessage(hit), ...this.messages];
});
},
Now, add the following HTML code to display the messages:
<div
v-for="message in messages"
:key="message._id"
:class="`messages ${message.username === username ? 'fromMe' : 'fromOthers'}`"
>
<span class="username">{{ message.username }}</span>
<span>({{ getDate(message.createdAt) }})</span>
<p>{{ message.value }}</p>
</div>
To finish this part, add the following CSS classes:
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.username {
font-weight: bold;
}
.messages {
padding: 10px;
margin: 1px;
width: 45vw;
border-radius: 10px;
}
.fromMe {
text-align: right;
float: right;
margin-left: 49vw;
background-color: #9ca4f0;
}
.fromOthers {
text-align: left;
margin-right: 49vw;
float: left;
background-color: rgb(206, 246, 147);
}
We can now display the messages stored in Kuzzle. All there is to do is to create some.
Send messages #
We need to write a simple method that will create a new message document in Kuzzle.
async sendMessage() {
if (this.message === "") return;
// Call the create method of the document controller
await kuzzle.document.create(
"chat",
"messages",
// Pass the document to be stored in Kuzzle as a parameter
{
value: this.message,
username: this.username
}
);
// Clear the user input
this.message = "";
},
As you can see we don't push the new message in our array on message creation.
Indeed, we will receive notifications from Kuzzle each time we modify our message collection (even if it is a message creation on our part) that we will use to add the messages in our array.
Now, we need to subscribe to the collection that contains our messages. So let's create our subscribeMessages()
action. It will call the Kuzzle's realtime controller to allow us to receive notifications on message creations:
async subscribeMessages() {
// Call the subscribe method of the realtime controller and receive the roomId
// Save the id of our subscription (we could need it to unsubscribe)
this.roomID = await kuzzle.realtime.subscribe(
"chat", // Id of the index
"messages", // Id of the collection
{}, // Filter
// Callback to receive notifications
notification => {
// Check if the notification interest us (only document creation)
if (notification.type !== "document") return;
if (notification.action !== "create") return;
// Add the new message to our array
this.messages = [
this.getMessage(notification.result),
...this.messages
];
}
);
},
To finish, just add an input field bound to the message
property, and a button which calls our sendMessage()
function:
<div class="wrapper" v-else>
<input
autofocus
type="text"
v-model="message"
v-on:keyup.enter="sendMessage"
placeholder="Enter your message"
/>
<button @click="sendMessage">Send</button>
</div>
And the following CSS class:
.wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
}
You can now add new messages to Kuzzle and receive the creation notification to update your state and display the new messages.
Where do we go from here? #
Now that you're more familiar with Kuzzle, dive even deeper to learn how to leverage its full capabilities:
- discover what this SDK has to offer by browsing other sections of this documentation
- learn more about Kuzzle realtime engine
- follow our guide to learn how to manage users, and how to set up fine-grained access control
- lean how to use Kuzzle Admin Console to manage your users and data
- learn how to perform a basic authentication