Backbone.js send a GET request only once? - javascript

socket.on('new message', function(data) {
self.createMessage(data);
});
createMessage: function(data) {
setTimeout(function() {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
}, 1000);
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
Let's say for example I have three sockets/users connected. When I run the code above each client makes that GET request three times (as many users that are connected). A bit annoying to me, it works well but I don't like the unnecessary requests.
It's a bit confusing because if I just appended some HTML like this.
createMessage: function(data) {
this.$el.find('.message-content').append('<div class="message"><b>'+data.username+':</b>'+data.message+'</div>');
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
Then that only happens once across all connected sockets/users not three times? But when I fetch GET then it want's to make that request three times, hmm? Any ideas, what am I missing?
Full Code: So there is no confusion
var Marionette = require('backbone.marionette'),
MessagesView = require('./messages'),
socket = io.connect();
module.exports = ChatView = Marionette.ItemView.extend({
className: 'chat',
template: require('../../templates/chat.hbs'),
events: {
'submit #chat-form': 'sendMessage'
},
initialize: function() {
var self = this;
this.messagesView = new MessagesView({ collection: window.App.data.messages });
socket.on('new message', function(data) {
self.createMessage(data);
});
},
onRender: function() {
this.$el.find('.message-content').append(this.messagesView.render().$el);
},
sendMessage: function(e) {
e.preventDefault();
var $message = this.$el.find('input.message');
$email = this.$el.parent().attr('data-email');
$username = this.$el.parent().attr('data-username');
var message = {
email : $email,
username: $username,
message : $message.val()
}
if($message.val() != '') {
socket.emit('send message', $message.val());
window.App.data.messages.create(message);
$message.val('');
}
window.App.core.vent.trigger('app:log', 'Chat View: Sent a new message!');
},
createMessage: function(data) {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
//this.$el.find('.message-content').append('<div class="message"><b>'+data.username+':</b>'+data.message+'</div>');
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
});

So the socket.io and backbone.js combination doesn't seem to popular. It's amazing technology IMO.
Okay so I found a solution, I forgot that while .fetch makes my GET requests, .create makes the POST request.
So by simply adding a call back to the .create method then on success I emit the data to the sockets, then return it to the client and make a GET request to all the sockets. Works like a charm, here is my solution.
var Marionette = require('backbone.marionette'),
MessagesView = require('./messages'),
socket = io.connect();
module.exports = ChatView = Marionette.ItemView.extend({
className: 'chat',
template: require('../../templates/chat.hbs'),
events: {
'submit #chat-form': 'sendMessage'
},
initialize: function() {
var self = this;
this.messagesView = new MessagesView({ collection: window.App.data.messages });
socket.on('new message', function(data) {
self.createMessage(data);
});
},
onRender: function() {
this.$el.find('.message-content').append(this.messagesView.render().$el);
},
sendMessage: function(e) {
e.preventDefault();
var $message = this.$el.find('input.message');
$email = this.$el.parent().attr('data-email');
$username = this.$el.parent().attr('data-username');
var message = {
email : $email,
username: $username,
message : $message.val()
}
if($message.val() != '') {
//window.App.data.messages.create(message);
window.App.data.messages.create({ message }, {
success: function() {
socket.emit('send message', $message.val());
}
});
$message.val('');
}
window.App.core.vent.trigger('app:log', 'Chat View: Sent a new message!');
},
createMessage: function(data) {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
});
This solves all my issues. For one I don't make an emission or any GET requests until the data is successfully on the server. Then after success I emit the data and then the .fetch() method only runs once for each socket!

Related

How to delete an event from fullcalendar on button click?

I'm in the middle of developing a drag and drop event fullcalendar with a resource column. I'm able to drag and drop events on the calendar and save it to the database. For the resource column, I have an add room button that allows users to add the room which also gets saved in the database. The resources and events are successfully being fetched and displayed on the calendar.
Now, I'm working on developing the delete functionality for the same. For now, I'm stuck at deleting the events using a double click.
Here's the code:
main.js
document.addEventListener("DOMContentLoaded", function() {
var containerEl = document.getElementById("external-events");
var checkbox = document.getElementById("drop-remove");
new FullCalendarInteraction.Draggable(containerEl, {
itemSelector: ".fc-event",
eventData: function(eventEl) {
return {
title: eventEl.innerText
};
}
});
var calendarEl = document.getElementById("calendar");
var calendar = new FullCalendar.Calendar(calendarEl, {
schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
plugins: ["interaction", "resourceTimeline", 'dayGrid', 'timeGrid' ],
header: {
left: "promptResource today prev,next",
center: "title",
right: 'dayGridMonth,resourceTimelineDay,resourceTimelineWeek'
},
customButtons: {
promptResource: {
text: "+ room",
click: function() {
var title = prompt("Room name");
console.log(title);
if (title) {
fetch("add_resources.php", {
method: "POST",
headers: {
'Accept': 'text/html'
},
body: encodeFormData({"title": title}),
})
.then(response => response.text())
.then(response => {
calendar.addResource({
id: response,
title: title
});
})
.catch(error => console.log(error));
}
}
}
},
editable: true,
aspectRatio: 1.5,
defaultView: "resourceTimelineDay",
resourceLabelText: "Rooms",
resources: "all_resources.php",
droppable: true,
drop: function(info) {
if (checkbox.checked) {
info.draggedEl.parentNode.removeChild(info.draggedEl);
}
},
eventLimit: true,
events: "all_events.php",
displayEventTime: false,
eventRender: function(event, element, view) {
if (event.allDay === "true") {
event.allDay = true;
} else {
event.allDay = false;
}
},
selectable: true,
selectHelper: true,
eventClick: function (info) {
var confimit = confirm("Do you really want to delete?");
if (confimit) {
$.ajax({
type: "POST",
url: "delete_event.php",
data: "&id=" + info.event.id,
success: function (response) {
if(parseInt(response) > 0) {
$('#calendar').fullCalendar('removeEvents', info.event.id);
displayMessage("Deleted Successfully");
}
}
});
}
},
eventReceive: function(info) {
console.log(calendar.getResources());
console.log(info.event);
var eventData = {
title: info.event.title,
start: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
end: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
resourceid: info.event._def.resourceIds[0]
};
console.log(eventData);
//send the data via an AJAX POST request, and log any response which comes from the server
fetch("add_event.php", {
method: "POST",
headers: {
Accept: "application/json"
},
body: encodeFormData(eventData)
})
.then(response => console.log(response))
.catch(error => console.log(error));
}
});
calendar.render();
});
const encodeFormData = data => {
var form_data = new FormData();
for (var key in data) {
form_data.append(key, data[key]);
}
return form_data;
};
delete_event.php
<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
if ($stmt->execute()) {
return $stmt->fetch(PDO::FETCH_ASSOC);
} else {
return null;
}
?>
When I'm trying to delete an event using the above code, I double click on the event, I see the message asking if I really want to delete the event, but it doesn't really get deleted. I don't see the delete_event.php being called in the network panel. The console has the error "ReferenceError: $ is not defined". I'm not sure what is wrong in the code above.
You need to make a few modifications to your code.
1) use fetch() instead of $.ajax, then you won't get any error messages about jQuery being missing. Ensure you put the event ID into the body of the request.
2) use the fullCalendar v4 syntax for eventClick, instead of v3 - see https://fullcalendar.io/docs/eventClick.
3) Remove the $stmt->fetch command from your PHP - a SQL DELETE operation doesn't return any results, so there is nothing to fetch. I also removed the meaningless return statements, because you're not inside a function, and your script doesn't have any further code which needs to be prevented from executing.
eventClick:
eventClick: function (info) {
var confimit = confirm("Do you really want to delete?");
if (confimit) {
fetch("delete_event.php", {
method: "POST",
body: encodeFormData({"id": info.event.id}) });
}
}
}
delete_event.php:
<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
if ($stmt->execute()) {
echo true;
} else {
echo false;
}
?>

How to save a variable to the server using jQuery

I am implementing a video conference room and I have a variable (room_status) which holds the status of the room (0 = close & 1 = open). Now this variable is only accessible my the client who clicks open-room.
I need to save the room_status variable to the server so that it can be accessed on other client's side. Here is a piece of my code:
var room_status = 0; //room closed
$('#open-room').click(function () {
// http://www.rtcmulticonnection.org/docs/open/
$.ajax({
type: 'GET',
url: "../invite",
data: {
videoconference_id: $('#meetingID').val(),
invitee_id: 1111,
status: "Accepted"
},
success: function() {
alert("success!");
},
error: function() {
alert("fail");
}
});
//room_status = 1; //room opened
rmc.open();
rmc.streams.mute({video : true});
document.getElementById("on-off-video").style.color= 'red';
});
$('#join-room').click(function () {
if(room_status) {
// http://www.rtcmulticonnection.org/docs/connect/
rmc.connect();
rmc.streams.mute({video: true});
document.getElementById("on-off-video").style.color= 'red';
} else {
console.log("Waiting for meeting organizer");
}
});
Ajax is your friend.
Here is an example from a prject of mine with jquery ui :
function prepare_ajax_button(l){
$("#button").button().click(function(event,ui){
$.ajax({type: "GET",data: {"arg1":l},url: "update_variable.php",success: function(data){
alert("Success ?!");
},error: function(data){alert("Problem ?!");}});
});
}
The page "update_variable.php" can for instance write the variable in a text file, mysql...

Getting a 500 internal server error thanks to some javascript in symfony

This is the code:
Controller:
public function isreadAction(Request $request) {
var_dump($request->get('sentValue'));
$em = $this->getDoctrine()->getEntityManager();
$pm = $this->getDoctrine()
->getRepository('LoginLoginBundle:Privatemessage')
->findBypmid($request->get('sentValue'));
$pm->setIsRead(true);
$em->flush();
return new Response();
}
js:
$(document).ready(function () {
$(".pmcontents").hide();
$(".pmbox").click(function () {
$(this).css("font-weight", "normal");
$(this).next().toggle();
var myValue = $('this').attr('id');
var DATA = 'sentValue=' + myValue;
$.ajax({
type: "POST",
url: Routing.generate('isread'),
data: DATA,
cache: false,
success: function (data) {
alert("database has been updated");
}
});
});
});
Routing:
isread:
path: /game/isread
defaults: { _controller: LoginLoginBundle:Default:isread }
requirements:
options:
expose: true
If i click on the error it says that the variable is undefined:
Parametersapplication/x-www-form-urlencodedNiet sorteren
sentValue undefined
Bron
sentValue=undefined
What is the problem? I have tried some things and it seems that the problem lies within the ajax part of the javascript, but i'm not sure.
Replace
var myValue = $('this').attr('id'); //<- notice quote around this
with
var myValue = $(this).attr('id');

How to call web service in sencha touch 2?

I 'm beginner in sencha touch 2 and i need to call webservice.The code of web service is:
public function loginAction()
{
$request = $this->getRequest();
$username = $request->request->get('username');
$password= $request->request->get('password');
$success=false;
$token="error";
$error="test";
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('username' => $username));
if (! $user)
{
$token="username not exists";
$success=false;
}
else
{
$password_user=$user->getPassword();
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword($password, $user->getSalt());
if ($password!=$password_user)
{
$token="password incorrect";
$success=false;
}
else
{
$token="logged";
$success=true;
}
}
$info= array("token" => $token);
$res=array("success"=> $success);
$res = array("status"=> $res,
"resultat"=>$info
);
$serializer = $this->get('jms_serializer');
$response = $serializer->serialize($res,'json');
return new Response($response);
}
and i make in project sencha a view: Login.js and a controller: Login.js. The problem is in calling the web service and the code in controller Login.js:
Ext.define('Sample.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginView: 'loginview',
mainMenuView: 'mainmenuview'
},
control: {
loginView: {
signInCommand: 'onSignInCommand'
},
mainMenuView: {
onSignOffCommand: 'onSignOffCommand'
}
}
},
// Session token
sessionToken: null,
// Transitions
getSlideLeftTransition: function () {
return { type: 'slide', direction: 'left' };
},
getSlideRightTransition: function () {
return { type: 'slide', direction: 'right' };
},
onSignInCommand: function (view, username, password) {
console.log('Username: ' + username + '\n' + 'Password: ' + password);
var me = this,
loginView = me.getLoginView();
if (username.length === 0 || password.length === 0) {
loginView.showSignInFailedMessage('Please enter your username and password.');
return;
}
loginView.setMasked({
xtype: 'loadmask',
message: 'Signing In...'
});
Ext.Ajax.request({
url: 'http://localhost/dawinilastversion/web/app_dev.php/api/login',
method: 'post',
params: {
username: username,
password: password
},
success: function (response) {
var loginResponse = Ext.JSON.decode(response.responseText);
if (loginResponse.success === "true") {
// The server will send a token that can be used throughout the app to confirm that the user is authenticated.
me.sessionToken = loginResponse.sessionToken;
me.signInSuccess(); //Just simulating success.
} else {
me.signInFailure(loginResponse.message);
console.log('erreur.');
}
},
failure: function (response) {
me.sessionToken = null;
me.signInFailure('Login failed. Please try again later.');
}
});
},
signInSuccess: function () {
console.log('Signed in.');
var loginView = this.getLoginView();
mainMenuView = this.getMainMenuView();
loginView.setMasked(false);
Ext.Viewport.animateActiveItem(mainMenuView, this.getSlideLeftTransition());
},
singInFailure: function (message) {
var loginView = this.getLoginView();
loginView.showSignInFailedMessage(message);
loginView.setMasked(false);
},
onSignOffCommand: function () {
var me = this;
Ext.Ajax.request({
url: 'http://localhost/dawinilastversion/web/app_dev.php/api/login',
method: 'post',
params: {
sessionToken: me.sessionToken
},
success: function (response) {
// TODO: You need to handle this condition.
},
failure: function (response) {
// TODO: You need to handle this condition.
}
});
Ext.Viewport.animateActiveItem(this.getLoginView(), this.getSlideRightTransition());
}
});
And the web service login work with success:
you need to go one step deeper into the JSON response:
if (loginResponse.status.success === true)
and check against the bool true not the string true

Backbone save model issues

I'm trying to save a model and on success, unrender it:
problem is that from within success i can't reference the this reference (which is the view) and I also cannot reference the variable isOk.status that this.model.save(...) returns.
the code:
save: function(e) {
e.preventDefault();
var isOk = this.model.save(null,
{
wait: true,
success: function(model, response){
console.log(response);
console.log(response.status);
},
error: function(model, response){
console.log("error");
console.log($.parseJSON(response.responseText));
$('#errorMessage').empty();
$('#errorMessage').append($.parseJSON(response.responseText).error);
$('#errorApproveModal').modal({
keyboard: true
});
}
});
console.log('logging isOk');
console.log(isOk);
//this one is working! It's on validate event
if(!isOk){
$('#errorMessage').empty();
$('#errorMessage').append("Error: there was an error");
$('#errorApproveModal').modal({
keyboard: true
});
return false
}
console.log(isOk);
**//both those checks are not working for some reason.**
//
if(isOk.status == 200 || isOk.statusText == "OK"){
console.log('in is ok');
this.remove();
}
return false;
}
Btw the view is:
App.Views.User = Backbone.View.extend({
model: App.Models.User
,
save: function...
});
Can someone please help?
Is there a better way to handle the success and error than this method?
Thanks!!
Roy
I'm not sure if this is the proper way to do it but I always just declare a variable referencing this from the view's function, then use that in success. Something like this:
save: function(e) {
// ADD THIS LINE
var me = this;
var isOk = this.model.save(null,
{
....
success: function(model, response){
// USE me IN HERE
me.render(); // e.g
},
....
}
You also can do this:
save: function(e) {
var isOk = this.model.save(null,
{
....
success: function(model, response,options){
// USE me IN HERE
this.options.me.render(); // e.g
},
//ADD me this
me : this
....
}
With the options,you can do all your parameters.

Categories

Resources