PresenceChannel not listening to the event of sending message - laravel

I'm currently using the channel to conduct one-on-one conversations amongst users, but despite my best efforts, the channel is not listening for the sendMessageEvent event.
this image shows that the event is fired
SendMessageEvent
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Console\Scheduling\Event;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Event as FacadesEvent;
class SendMessageEvent implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
public $roomId;
public $fromId;
public $status;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($message,$user,$roomId,$fromId,$status)
{
$this->message = $message;
$this->user = $user;
$this->roomId = $roomId;
$this->fromId = $fromId;
$this->status = $status;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('message.'.$this->roomId);
}
public function broadcastAs(){
return 'chat-message';
}
public function broadcastWith()
{
return [
'id'=>$this->fromId,
'name'=>$this->user,
'message'=>$this->message,
'status'=>$this->status,
];
}
}
frontend javascript
#push('head')
<meta name="csrf-token" content="{{ csrf_token() }}">
#vite(['resources/js/app.js'])
{{-- <script type="module" src="{{ asset('js/privateMessage.js') }}"></script> --}}
<script type="module">
let token = $('meta[name="csrf-token"]').attr('content');
//form-id
let form = document.getElementById('form');
//input-message
let inputMessage = document.getElementById('input-message');
//container-message
let container = document.getElementById('container-message');
//room-id
let roomid = document.getElementById('room-id');
const roomId = roomid.value;
//other-user-id
let touserId =document.getElementById('touserId');
const toUserId = touserId.value;
let send = document.getElementById('send-btn');
let typing = document.getElementById('typing');
let status = document.getElementById('status');
let read_message = document.querySelectorAll('.fa-check-double.unreaded');
//array of online users in both sides
let usersOnline = [];
//create new channel and make pass room id to it
let channel = Echo.join(`message.${roomId}`).listen('.chat-message',(event)=>{
console.log('.chat-message');
create_message(event)
});
console.log(channel);
//add status code 1 => online , 0 => offline
function add_status_code()
{
let status_code = 0
usersOnline.forEach(user => {
if(user.id == toUserId){
status_code = 1
}
});
return status_code
}
//check message status in front view
function check_message_status(message)
{
let status_t = 'unreaded'
if(message.status == 1){
status_t = 'readed'
}
return status_t
}
//create message
function create_message(message)
{
let status_t = check_message_status(message)
console.log(status_t)
console.log('aaamk');
var today = new Date();
var time = today.toLocaleTimeString();
if(message.id == '{{Auth::id()}}'){
container.innerHTML +=`
<div class="message text-only">
<div class="response">
<p class="text">${message.message}</p>
</div>
</div>
<p class="time my_time">${time} <i class="fa-sharp fa-solid fa-check-double ${status_t}"></i></p>
`
}else{
var today = new Date();
var time = today.toLocaleTimeString();
container.innerHTML +=`
<div class="message">
<div class="photo" style="background-image: url(https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80);">
<div class="online"></div>
</div>
<p class="text"> ${message.message} </p>
</div>
<p class="time">${time}</p>
`;
}
}
//read message in typing
function read_all_message()
{
usersOnline.forEach(user => {
if(user.id == toUserId){
let readedd = document.querySelectorAll('.fa-check-double.unreaded');
readedd.forEach(el=>{
el.className = 'fa-sharp fa-solid fa-check-double readed';
})
$.ajax({
method: "POST",
url: "/read_all",
data: {
toId: toUserId,
roomId: roomId,
_token: token
},
});
}
});
}
// show in typing
// inputMessage.addEventListener('input',function(event){
// if(inputMessage.value.length == 0){
// channel.whisper('stop-typing');
// }else{
// channel.whisper('typing',{
// name: "{{$user->display_name}}"
// })
// console.log('typingsss');
// }
// })
//on submit
form.addEventListener('submit',function(event){
const userInput = inputMessage.value;
event.preventDefault();
let status_code = add_status_code()
$.ajax({
method: "POST",
url: "/send",
data: {
message: userInput,
roomid:roomId,
touserId:toUserId,
status:status_code,
_token: token
},
});
// channel.whisper('stop-typing');
// channel.whisper('message-sent',event);
inputMessage.value="";
})
SendMessageController
public function sendMessage(Request $request){
$fromId = Auth::id();
$toUserId = $request->touserId;
$message = $request->message;
$status = $request->status;
$email = Auth::user()->email;
$user = Auth::user()->display_name;
$id = $request->roomid;
$save_message = Message::create([
'message'=>$message,
'from_id'=>$fromId,
'to_id'=>$toUserId,
'chat_id'=>$id,
'is_readed'=>$status,
]);
broadcast(new SendMessageEvent($message,$user,$id,$fromId,$status))->toOthers();
return null;
}
l tried
broadcast(new SendMessageEvent($message,$user,$id,$fromId,$status))->toOthers();
event(new SendMessageEvent($message,$user,$id,$fromId,$status));
let channel = Echo.join(message.${roomId}).listen('.chat-message',(event)=>{
console.log('.chat-message');
create_message(event)
});
let channel = Echo.join(message.${roomId}).listen('SendMessageEvent',(event)=>{
console.log('.chat-message');
create_message(event)
});
let channel = Echo.join(message.${roomId}).listen('\App\Events\SendMessageEvent',(event)=>{
console.log('.chat-message');
create_message(event)
});
let channel = Echo.join(message.${roomId}).listen('\App\Events\SendMessageEvent',(event)=>{
console.log('.chat-message');
create_message(event)
});

Related

websocket dont listen to changes when the message has been sent and it need to refresh to show current sent message

The websocket isn't updating every time I send a message, so I have to refresh the browser before the message appears. I'm trying to establish one-to-one chat messages in my program, but there are issues.
I am using Laravel 9.48.0
Send Message Event
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class SendMessage implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
public $roomId;
public $fromId;
public $status;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($message,$user,$roomId,$fromId,$status)
{
$this->message = $message;
$this->user = $user;
$this->roomId = $roomId;
$this->fromId = $fromId;
$this->status = $status;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('message.'.$this->roomId);
}
public function broadcastAs()
{
return 'chat-message';
}
public function broadcastWith()
{
return [
'id'=>$this->fromId,
'name'=>$this->user,
'message'=>$this->message,
'status'=>$this->status,
];
}
}
channels.php
Broadcast::channel('chatroom', function ($user) {
return $user;
});
Broadcast::channel('App.Models.User.*', function ($user, $id) {
return (int) $user->user_id === (int) $id;
});
Broadcast::channel('message.{message_id}', function ($user, $id) {
return $user;
});
BroadcastServiceProvider
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
bootstrap.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Echo from 'laravel-echo';
console.log('hee');
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
Frontend
let token = $('meta[name="csrf-token"]').attr('content');
//form-id
let form = document.getElementById('form');
//input-message
let inputMessage = document.getElementById('input-message');
//container-message
let container = document.getElementById('container-message');
//room-id
let roomid = document.getElementById('room-id');
const roomId = roomid.value;
//other-user-id
let touserId =document.getElementById('touserId');
const toUserId = touserId.value;
let send = document.getElementById('send-btn');
let typing = document.getElementById('typing');
let status = document.getElementById('status');
let read_message = document.querySelectorAll('.fa-check-double.unreaded');
//array of online users in both sides
let usersOnline = [];
//create new channel and make pass room id to it
const channel = Echo.join(`message.${roomId}`);
//add status code 1 => online , 0 => offline
function add_status_code()
{
let status_code = 0
usersOnline.forEach(user => {
if(user.id == toUserId){
status_code = 1
}
});
return status_code
}
//check message status in front view
function check_message_status(message)
{
let status_t = 'unreaded'
if(message.status == 1){
status_t = 'readed'
}
return status_t
}
//create message
function create_message(message)
{
let status_t = check_message_status(message)
console.log(status_t)
console.log('aaamk');
var today = new Date();
var time = today.toLocaleTimeString();
if(message.id == '{{Auth::id()}}'){
container.innerHTML +=`
<div class="message text-only">
<div class="response">
<p class="text">${message.message}</p>
</div>
</div>
<p class="time my_time">${time} <i class="fa-sharp fa-solid fa-check-double ${status_t}"></i></p>
`
}else{
var today = new Date();
var time = today.toLocaleTimeString();
container.innerHTML +=`
<div class="message">
<div class="photo" style="background-image: url(https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80);">
<div class="online"></div>
</div>
<p class="text"> ${message.message} </p>
</div>
<p class="time">${time}</p>
`;
}
}
//read message in typing
function read_all_message()
{
usersOnline.forEach(user => {
if(user.id == toUserId){
let readedd = document.querySelectorAll('.fa-check-double.unreaded');
readedd.forEach(el=>{
el.className = 'fa-sharp fa-solid fa-check-double readed';
})
$.ajax({
method: "POST",
url: "/read_all",
data: {
toId: toUserId,
roomId: roomId,
_token: token
},
});
}
});
}
//show in typing
inputMessage.addEventListener('input',function(event){
if(inputMessage.value.length == 0){
channel.whisper('stop-typing');
}else{
channel.whisper('typing',{
name: "{{$user->name}}"
})
}
})
//on submit
form.addEventListener('submit',function(event){
const userInput = inputMessage.value;
event.preventDefault();
let status_code = add_status_code()
$.ajax({
method: "POST",
url: "/send",
data: {
message: userInput,
roomid:roomId,
touserId:toUserId,
status:status_code,
_token: token
},
});
channel.whisper('stop-typing');
inputMessage.value="";
})
channel.here((users)=>{
usersOnline = [...users]
console.log({usersOnline},'Here')
usersOnline.forEach(user => {
if(user.id == toUserId){
status.innerHTML = "Online";
}
});
})
.joining((user) => {
usersOnline.push(user);
console.log({usersOnline},'Join')
usersOnline.forEach(user => {
if(user.id == toUserId){
status.innerHTML = "Online";
}
});
})
.leaving((user) => {
usersOnline = usersOnline.filter((usersOnline)=> usersOnline.id !== user.id);
usersOnline.forEach(user => {
if (user.id != toUserId){
status.innerHTML = "Offline";
}
});
})
.listen('chat-message',(event)=>{
console.log('chat-message');
create_message(event)
})
.listenForWhisper('typing',(event)=>{
console.log('typing');
typing.innerHTML = "typing..";
read_all_message()
})
.listenForWhisper('stop-typing',(event)=>{
typing.innerHTML = "";
console.log('stop-typing');
})

Symfony 5 ajax post form

I need to make dynamic form in symfony 5 with ajax.
I make post request with axios on input value change on main route "/".
This route call my controller and i call dump() function for debug my request but i don't have any params on my request.
I looked in my network and my data is posted well. But I don't receive params on my request controller :/
On my view
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
cat = document.getElementById("article_category")
token = document.querySelector("#article__token");
title = document.querySelector("#article_title");
cat.addEventListener("change", function (e) {
let form = document.querySelector("form")
let data = {}
data[title.getAttribute("name")] = title.value
data[token.getAttribute("name")] = token.value
data[cat.getAttribute("name")] = cat.value
axios.post("https://127.0.0.1:8000/", data).then(res => {
str = res.data
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text/html')
console.log(doc);
}).catch(function (error) {
console.log(error);
});
})
</script>
My Controller
/**
* #Route("/", name="article")
*/
public function index(Request $request, EntityManagerInterface $em): Response
{
$article = new Article();
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
dump($request);
}
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($article);
$em->flush();
}
return $this->render('article/index.html.twig', [
"form" => $form->createView(),
]);
}
FormType
$builder
->add('title')
->add('category')
->add('Submit', SubmitType::class);
$builder->get('category')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
if ($form->getData()->getName() == "Cat 0") {
$form->getParent()->add('tag', EntityType::class, [
'class' => Tag::class,
]);
}
}
);

Ajax call, displaying a json response instead of success?

I have a form with a click event on submit button like this:
<div class="col-md-6 col-md-offset-4" id="submit_div">
<button type="submit" id="submit" class="btn btn-warning" onclick="entity();">
Update Entity
</button>
</div>
ajax:
$(document).ready(function() {
function entity() {
$.ajax({
url: 'entity/create/add',
type: 'post',
dataType: 'JSON',
success: function(data) {
$('#submit_div').html('<button type="button" class="btn.btn-success">Edit</button')
},
error: function(data) {
alert("Oh no!");
},
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content');
}
});
}
});
controller:
public function store(EntityRequestCreate $request)
{
$geoloc = new Geoloc;
$geoloc->lat = $request->input('lat');
$geoloc->lng = $request->input('lng');
$geoloc->slug = $request->input('name');
$geoloc->save();
$user_id = Auth::id();
$entity = new Entity;
$entity->name = $request->input('name');
$entity->type = $request->input('type');
$entity->email = $request->input('email');
$entity->tags = $request->input('tags');
$entity->_geoloc()->associate($geoloc);
$entity->save();
$entity_id = $entity->id;
$address = new Address;
$address->building_name = $request->input('building_name');
$address->address = $request->input('address');
$address->town = $request->input('town');
$address->postcode = $request->input('postcode');
$address->telephone = $request->input('telephone');
$address->entity_id = $entity_id;
$address->save();
$role = User::find($user_id);
$role->role = "2";
$role->save();
DB::table('entity_user')->insert(array('entity_id' => $entity_id, 'user_id' => $user_id));
$result = $geoloc->save();
$result2 = $entity->save();
$result3 = $address->save();
$result4 = $role->save();
if ($result && $result2 && $result3 && $result4) {
$data = $entity_id;
} else {
$data = 'error';
}
return response()->json(['results' => $data]);
}
route:
Route::post('entity/create/add', 'EntityController#store');
Everything seems to work, there are no errors but instead of a button from success(data) I get the actual response:
{
"results": 112
}
But I don't even know why it is happening can someone please help me?
form doesn't have any action and it looks like ajax is not being called?

How to apply diffForHumans() in laravel using ajax?

I'm working with laravel and native ajax. I am wondering where do I put diffForhHumans() when using ajax. In my Controller. I just return the object fetch.
Here's my Controller
public function getDownlines($id) {
$upline = Upline::find($id);
return $upline->downlines;
}
Model
public function downlines() {
return $this->hasMany('App\Downline');
}
HTML Code in View
<div id="downlines">
<div class="downlines-title-container">
<p class="title"></p>
</div>
<div id="downlines-holder">
<div class="p_parent_header">
<p>ID</p>
<p>Account Code</p>
<p>Created By</p>
<p>Created At</p>
</div>
</div>
</div>
Script in Ajax
var downlines = document.getElementById('downlines'),
downlines_holder = document.getElementById('downlines-holder');
function getPromise(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
if(xhr.status == 200) {
resolve(xhr.response);
} else {
reject(Error(xhr.statusText))
}
}
xhr.onerror = function() {
reject(Error('Network Error'));
};
xhr.send();
})
}
function getDownlines(e, id) {
getPromise('upline/getdownlines/' + id).then(function(response) {
var resp = JSON.parse(response),
p_parent = document.getElementsByClassName('p_parent'),
p = p_parent.length;
while(p--) p_parent[p].remove();
if(resp.length > 0) {
downlines.style.display = 'initial'
downlines.children[0].children[0].innerHTML = e.innerHTML;
for(var i = 0; i < resp.length; i++) {
var p_parent = document.createElement('div'),
p1 = document.createElement('p'),
p2 = document.createElement('p'),
p3 = document.createElement('p'),
p4 = document.createElement('p');
p_parent.classList.add('p_parent');
p1.innerHTML = resp[i].id;
p2.innerHTML = resp[i].account_code;
p3.innerHTML = resp[i].created_by;
p4.innerHTML = resp[i].updated_at;
p_parent.appendChild(p1);
p_parent.appendChild(p2);
p_parent.appendChild(p3);
p_parent.appendChild(p4);
downlines_holder.appendChild(p_parent);
}
} else {
downlines.style.display = 'none'
}
}, function(error) {
console.log(error);
})
}
I'm searching for the same problem and doesn't find one.
Any help would be appreciated. Thanks!!!
Please do this before returning the downlines
public function getDownlines($id)
{
$upline = Upline::find($id);
return $upline->downlines->map(function($downline) {
return [
'id' => $downline->id,
'account_code' => $downline->account_code,
'created_by' => $downline->created_by,
'created_at' => $downline->created_at->diffForHumans(),
'updated_at' => $downline->updated_at->diffForHumans(),
];
});
}
I am unsure if you want to use created_at or updated_at, because in the html you have written <p>Created At</p> but in the AJAX request, you have written p4.innerHTML = resp[i].updated_at;. So I added both in the return array :)

how return value to display message in codeignaitor

i have controller that delete row from database like :-
public function deletePost() {
$events = new event_model();
$ev_id=intval($_POST['ev_id']);
$result = $events->deletePostWall($ev_id);
}
and the model is :-
function deletePostWall($ev_id) {
$vales = array('ev_id' => $ev_id);
$vales_comment = array('co_postid' => $ev_id);
$query_done = $this->db->delete($this->table_name, $vales) or die (mysql_error());
$query_done_comment = $this->db->delete('comment', $vales_comment) or die (mysql_error());
}
now this method is work good, but i need when delete success, send message in view to user that the delete is done.
how can do that.
you can try this
in controller
public function deletePost() {
$events = new event_model();
$ev_id=intval($_POST['ev_id']);
$result = $events->deletePostWall($ev_id);
$this->session->set_flashdata('msg','Delete is done');
redirect('controller_name/function_name','refresh');//redirect a function which loads your view.
}
in view
<?php if($this->session->flashdata('msg')){echo $this->session->flashdata('msg');}?>
model
function deletePostWall($ev_id) {
$vales = array('ev_id' => $ev_id);
$vales_comment = array('co_postid' => $ev_id);
$query_done = $this->db->delete($this->table_name, $vales) or die (mysql_error());
$query_done_comment = $this->db->delete('comment', $vales_comment) or die(mysql_error());
return $this->db->affected_rows();
}
controller
public function deletePost() {
$events = new event_model();
$this->data['message'] = '';
if($this->input->post()) {
$ev_id=intval($this->input->post('ev_id'));
$result = $events->deletePostWall($ev_id);
if($result) {
$this->data['message'] = "Deleted!";
}
else {
$this->data['message'] = "Not Deleted!";
}
}
$this->load->view('VIEW-NAME',$this->data);
}
view
<html>
<head>
</head>
<body>
<h1><?php echo $message; ?></h1>
</body>
</html>
controller:
public function deletePost() {
$events = new event_model();
$ev_id=intval($_POST['ev_id']);
$result = $events->deletePostWall($ev_id);
if($result) {
$this->data['success'] = "Deleted!";
$this->load->view('VIEW-NAME',$this->data);
}
}
Method:
function deletePostWall($ev_id) {
$vales = array('ev_id' => $ev_id);
$vales_comment = array('co_postid' => $ev_id);
$query_done = $this->db->delete($this->table_name, $vales) or die (mysql_error());
$query_done_comment = $this->db->delete('comment', $vales_comment) or die(mysql_error());
return $this->db->affected_rows();
}
View:
<html>
<head>
<title>title</title>
</head>
<body>
<h1><?php if (isset($success)) {echo $success;}?></h1>
</body>
</html>

Resources