I cannot get my events working on laravel 7.x, pusher, laravel-echo. I have set up everything correctly but still getting 401 error. I have also set up broadcast_driver as pusher in .env file. If anyone can help, I will appreciate.
CommentEvent.php
<?php namespace AppEvents; use IlluminateBroadcastingChannel; use IlluminateBroadcastingInteractsWithSockets; use IlluminateBroadcastingPresenceChannel; use IlluminateBroadcastingPrivateChannel; use IlluminateContractsBroadcastingShouldBroadcast; use IlluminateFoundationEventsDispatchable; use IlluminateQueueSerializesModels; class CommentEvent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $comment; /** * Create a new event instance. * * @return void */ public function __construct($comment) { $this->comment =$comment; } /** * Get the channels the event should broadcast on. * * @return IlluminateBroadcastingChannel|array */ public function broadcastOn() { return new Channel('comment-channel'); } public function broadcastAs() { return 'newComment'; } }
CommentController.php
<?php namespace AppHttpControllers; use IlluminateHttpRequest; use AppEventsCommentEvent; use AppComment; class CommentController extends Controller { public function index(){ return view('comments'); } public function fetchComments(){ $comments =Comment::all(); return response()->json($comments); } public function store(Request $request){ $comment =Comment::create($request->all()); event(new CommentEvent($comment)); return response()->json('ok'); } }
/routes/channels.php
<?php use IlluminateSupportFacadesBroadcast; /* |-------------------------------------------------------------------------- | Broadcast Channels |-------------------------------------------------------------------------- | | Here you may register all of the event broadcasting channels that your | application supports. The given channel authorization callbacks are | used to check if an authenticated user can listen to the channel. | */ // Broadcast::channel('App.User.{id}', function ($user, $id) { // return (int) $user->id === (int) $id; // }); Broadcast::channel('comment-channel', function () { return true; });
bootstrap.js
window._ = require('lodash'); try { window.Popper = require('popper.js').default; window.$ = window.jQuery = require('jquery'); require('bootstrap'); } catch (e) {} window.axios = require('axios'); window.moment = require('moment'); window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; window.axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; window.axios.defaults.headers.common.crossDomain = true; // window.axios.defaults.baseURL = '/api'; let token = document.head.querySelector('meta[name="csrf-token"]'); if (token) { window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; } else { console.error('CSRF token not found: https://adonisjs.com/docs/4.1/csrf'); } import Echo from 'laravel-echo'; window.Pusher = require('pusher-js'); window.Echo = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, cluster: process.env.MIX_PUSHER_APP_CLUSTER, forceTLS: true });
store.js
import Vue from 'vue'; import Vuex from 'vuex'; import axios from 'axios'; Vue.use(Vuex); export const store =new Vuex.Store({ state:{ //stores all the comments in this array// comments:[] }, getters:{ //returns the comments array// comments:state=>{ return state.comments } }, mutations:{ //populates the comments array in the state with the comments from the database// getComments:(state,comments)=>{ state.comments =comments }, addComment:(state,comment)=>{ state.comments = state.push(comment) } }, actions:{ /* gets all the comments from comments endpoint api*/ getComments:({commit})=>{ axios.get(`http://127.0.0.1:8000/api/comments`) .then(res=>{ //commits getcomments mutation and passes a parameter of comments from the response// commit('getComments',res.data) }) .catch(err=>{ console.log(err) }) }, addComment:({commit},comment)=>{ return new Promise((resolve,reject)=>{ axios.post(`http://127.0.0.1:8000/api/comments`,{ author:comment.author, content:comment.content }) .then(res=>{ resolve(res) }).catch(err=>{ reject(err) }) }) } } })
MainApp.vue
<template> <div class="container"> <div class="row"> <div class="col"> <div class="card"> <div class="card-body"> <form @keyup.enter="postComment"> <div class="form-group"> <input type="text" class="form-control" placeholder="Author's Name" v-model="comment.author"> </div> <div class="form-group"> <textarea name="comment" id="" rows="6" class="form-control" v-model="comment.content" > </textarea> </div> <div class="form-group"> <input type="submit" value="Submit" class="btn btn-success" @click.prevent="postComment"> </div> </form> </div> </div> </div> <div class="col"> <div class="card"> <div class="card-body"> <div class="media" v-for="comment in comments" :key="comment.id"> <img class="mr-3" src="https://api.adorable.io/avatars/48/@adorable.io.png" alt="Generic placeholder image"> <div class="media-body"> <h5>{{comment.author}}</h5> {{comment.content}} </div> </div> </div> </div> </div> </div> </div> </template> <script> import {store} from '../store'; import {mapGetters} from 'vuex'; import {mapActions} from 'vuex'; export default { store:store, data:function(){ return{ comment:{ author:'', content:'' } } }, mounted() { //calls the action getcomments from store.js// this.$store.dispatch('getComments'); Echo.channel('comment-channel') .listen('.newComment', (e)=>{ console.log(e) }) }, computed:{ //gets the comments array from store.js// ...mapGetters([ 'comments' ]) }, methods:{ postComment:function(){ this.$store.dispatch('addComment',this.comment) .then(res=>{ if(res==='ok'){ console.log('success') } }).catch(err=>{ console.log(err) }) } } } </script>
Advertisement
Answer
Make sure to pass $user into the channel route callback. replace this code with your channel route. then you are good to go 🙂
Broadcast::channel('comment-channel', function ($user) { return true; });