I'm implementing the pubnub chat in my AngularJS application. I'm following this tutorial
The problem is that if I create a new AngularJS application from scratch the chat works, but if I implement the code in my already existing application I get this error:
Missing Callback pubnub.min.js:1
And I can't see messages that I write and messages that I should receive but I can send them and I can see those messages on the other side of the chat.
Do you know how can I solve this problem?
EDIT: this is the controller for the pubnub chat:
'use strict';
angular.module('myApp.appointments', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
}])
.controller('appointmentsCtrl', ["$rootScope", "$scope", "$http", "$timeout", "$cookies", "URL", "Pubnub", function($rootScope, $scope, $http, $timeout, $cookies, URL, Pubnub) {
$scope.sortType = 'name';
$scope.sortReverse = false;
$scope.sortType_s = 'time';
$scope.filterAppointments = false;
$scope.filterDate = '';
$scope.highlightRow = '';
$scope.$on('$routeChangeSuccess', function() {
var data = {
"token":$cookies.get('userToken'),
"hairdresser_id": $cookies.get('userId')
};
$http.post(URL.url + 'appointments', data).then(function(res){
$scope.app_list = res.data.appointments;
$scope.service_list = res.data.appointment_services;
$scope.customers_list = res.data.customers;
$scope.pending_number = res.data.pending;
});
data = {
"token":$cookies.get('userToken'),
"hairdresser_id": $cookies.get('userId')
};
$http.post(URL.url + 'monthly_earnings', data).then(function(res){
$rootScope.monthly_earnings = res.data.amount;
});
});
// Pubnub implementation
$scope.channel = "messages-channel";
$scope.uuid = _.random(100).toString();
Pubnub.init({
publish_key: MY_KEY,
subscribe_key: SUB_KEY,
ssl: true,
uuid: $scope.uuid
});
$scope.sendMessage = function() {
if (!$scope.messageContent || $scope.messageContent === '') {
return;
}
Pubnub.publish({
channel: $scope.channel,
message: {
content: $scope.messageContent,
sender_uuid: $scope.uuid,
date: new Date()
},
callback: function(m) {
console.log(m);
}
});
$scope.messageContent = '';
}
$scope.messages = [];
Pubnub.subscribe({
channel: $scope.channel,
triggerEvent: ['callback']
});
$scope.$on(Pubnub.getMessageEventNameFor($scope.channel), function(ngEvent, m) {
$scope.apply(function() {
$scope.messages.push(m)
});
});
}]);
You forgot the s at the end of the triggerEvents statement in the Pubub.subscribe function :
Pubnub.subscribe({
channel: $scope.channel,
triggerEvents: ['callback']
});
Let me know if it has solved your issue.
Related
I am creating whatsapp application by using PubNub Api and ionic platform. However, it comes with problem that ionic.bundle.js:21157 TypeError: PubNub.publish is not a function. Below is my code. Can anyone help me?
var chat = angular.module('chat', ['pubnub.angular.service']);
chat.controller('chatController', ['$scope', '$state', '$rootScope',
'$stateParams', 'PubNub', '$http', '$ionicScrollDelegate',
function($scope, $state, $rootScope, $stateParams, PubNub, $http,
$ionicScrollDelegate){
var nickname = $stateParams.nickname;
var channel = $stateParams.channel;
$scope.messageContent = '';
$scope.messages = [];
$scope.goBack = function() {
$state.go('channels',{nickname: nickname, channel: channel});
}
PubNub.init({
publish_key:'',
subscribe_key:'',
ssl: true,
nickname: nickname
});
$scope.sendMessage = function() {
if (!$scope.messageContent ||
$scope.messageContent === '') {
return;
}
PubNub.publish({
channel: channel,
message: {
content: $scope.messageContent,
nickname: nickname
},
callback: function(m) {
console.log(m);
}
});
$scope.messageContent = '';
}
PubNub.ngSubscribe({channel: channel});
$rootScope.$on(PubNub.ngMsgEv(channel), function(event, payload) {
$scope.$apply(function() {
$scope.messages.push(payload.message);
$ionicScrollDelegate.scrollBottom();
console.log(payload.message);
});
});
}]);
The name of the service to inject is Pubnub instead of PubNub.
I am trying to make a real time chat in ionic in which the messages are logged in firebase but I'm receiving this error:
Error: $scope.chats.$add is not a function
The code it suppose to separate the messages by groups and when a message is sent it will send my chats to the firebase using $add
And here is my code:
angular.module('starter.controllers', ["ionic",'firebase'])
.controller('ChatsCtrl', ['$scope', '$stateParams', '$firebaseArray', '$rootScope', '$ionicHistory', '$state',
function($scope, $stateParams, $firebaseArray, $rootScope, $ionicHistory, $state) {
$rootScope.notifyIonicGoingBack = function() {
$state.go('groups');
}
$scope.$myBack = function() {
$ionicHistory.goBack();
$rootScope.notifyIonicGoingBack();
};
console.log('state ' + $stateParams);
var ref = new Firebase('https://projectxu.firebaseio.com/chats') //USE OUR Firebase FOR CHAT!!
$scope.sender_id = 1;
$scope.group_id = $stateParams.group_id;
var sync = $firebaseArray(ref);
sync.$loaded(function (data) {
var filtered_chats = new Array();
angular.forEach(data, function(value, key) {
if(value.group_id == $scope.group_id) {
filtered_chats.push(value);
}
});
$scope.chats = filtered_chats;
});
$scope.sendChat = function(chat){
console.log("MESSAGE SENT");
//if($rootScope.authData){
/* $scope.chats.$add({
user: $rootScope.authData.facebook.username, //SWITCH TO FACEBOOK!!!
message: chat.message,
imgURL: $rootScope.authData.facebook.cachedUserProfile.profile_img_url
});
*/
$scope.chats.$add({
sender_id: $scope.sender_id, //SWITCH TO FACEBOOK!!!
message: chat.message,
group_id: $scope.group_id,
timestamp: new Date().getTime(),
//sender_name: $rootScope.authData.facebook.cachedUserProfile.displayName,
//imgURL: $rootScope.authData.facebook.cachedUserProfile.profile_img_url
});
chat.message ="";
console.log("MESSAGE");
}
}])
I would like to create a $http.get service properly but I have trouble with services in AngularJS. I create this code and It works but all the code is in the controler :
var monApp = angular.module('monApp', []);
monApp .controller('PhoneListCtrl', ['$scope', '$http',
function($scope, $http) {
$http.get('http://port:serveur/fichier.xml').then(function(response) {
var x2jObj = X2J.parseXml(response.data); //X2J.parseXml(xmlDocument, '/');
var tableauJSON = X2J.getJson(x2jObj);
}, function(a, b, c) {
alert("Impossible de télécharger le fichier");
});
}
]);
Can you help me to create it in service ?
Thanks.
create a service with name fichierService and a function getData like
monApp.factory("fichierService", function($http) {
return {
getData: function() {
return $http.get('http://port:serveur/fichier.xml');
}
}
});
and use that fichierService service in your PhoneListCtrl controller by inject
monApp .controller('PhoneListCtrl', ['$scope', '$http','fichierService',
function($scope, $http, fichierService) {
fichierService.getData().then(function(response) {
// rest of code
}, function(a, b, c) {
alert("Impossible de télécharger le fichier");
});
}
]);
monApp.service('myFooService', function() {
this.get = function (url) {
return $http.get(url).then(function(response) {
var x2jObj = X2J.parseXml(response.data);
var tableauJSON = X2J.getJson(x2jObj);
});
}
});
and then you can use your service like this
monApp.controller('fooCtrl', function($scope, myFooService) {
myFooService.get('http://foo.com/foo.xml');
});
This should give an idea on how to start implementing your own service.
This is the perfect solution, the controler :
var app = angular.module("myApp", []);
app.controller("MainCtrl", ["$scope", "userService",
function($scope, userService) {
userService.getData();
}
]);
The web service :
app.service("userService",["$http",
function($http) {
_this = this;
this.getData = function() {
$http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"};
$http.defaults.headers.common['Authorization'] = 'Basic ' + window.btoa('username' + ':' + 'password');
$http.get('http://YourServer:YourPort/rest/api/2/auditing/record').
success(function(data) {
console.log(data);
});
}
}
]);
I am trying to redirect users to a login page if they make an attempt to access pages that require them to be logged in. I am using Firebase and AngularJS, following this guide. The error explanation on the AngularJS site indicates that either a non-existent definition or duplicate definition is causing the issue but I cannot identify either of these in my code. Additionally, the stack trace of the error doesn't indicate which of my files caused the error, only mentioning the angular.js file.
Can anyone give me some insight as to what is causing this issue?
Note: The site runs without errors and users can log in and out if I leave out the resolve section of the $routeProvider.
Here is my app.js
angular.module('richWebApp', ['ngRoute', 'firebase', 'objectFilter'])
.constant('fb', {
url: 'https://<my-firebase-app>.firebaseio.com/' //name removed for security reasons
})
.run(function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, next, previous, error) {
if(error === "AUTH_REQUIRED") {
$location.path("/login");
}
});
})
.config(function($routeProvider){
$routeProvider.
when('/login', {
templateUrl: 'pages/login/login.html'
}).
when('/main', {
templateUrl: 'pages/main/main.html',
resolve: {
"currentAuth": ["Auth", function(Auth) {
return Auth.$requireAuth();
}]
}
}).
when('/thread/:threadId', {
templateUrl: 'pages/thread/thread.html',
resolve: {
"currentAuth": ["Auth", function(Auth) {
return Auth.$requireAuth();
}]
}
}).
otherwise({
redirectTo: '/login'
});
});
Here is the main.js controller
angular.module('richWebApp')
.controller('mainPageController', function($scope, $location, userService, currentAuth, threadService, fb, $firebaseAuth, $filter){
$scope.user = userService.getLoggedInUser();
$scope.newThreadTitle = '';
$scope.threadSubject = ''
$scope.createNewThread = false;
$scope.sortBy = 'dateAdded'
$scope.threads = threadService.getAllThreads();
$scope.getSubjects = function(subject) {
return $scope.threads.subject;
}
$scope.beginAddThread = function() {
$scope.createNewThread = true;
}
$scope.addThread = function(){
if(!$scope.newThreadTitle || !$scope.newThreadSubject){
return false;
}
var date = new Date();
var newThread = {
title: $scope.newThreadTitle,
subject: $scope.newThreadSubject,
username: $scope.user.name,
numComments: 0,
comments: [],
dateAdded: date.getTime()
};
$scope.threads.$add(newThread);
$scope.newThread = '';
$scope.newThreadTitle = '';
$scope.newThreadSubject = '';
$scope.createNewThread = false;
}
$scope.sortByDate = function() {
$scope.sortBy = 'dateAdded';
}
$scope.sortByPopularity = function() {
$scope.sortBy = 'numComments';
}
$scope.searchSubject = function(subject) {
$scope.searchThread = subject;
}
$scope.logout = function(){
userService.logout();
}
});
Here is the thread.js controller
angular.module('richWebApp')
.controller('threadPageController', function($scope, $location, $routeParams, $filter, currentAuth, threadService, fb, userService){
var threadId = $routeParams.threadId;
$scope.newComment = '';
var thread = threadService.getThread(threadId);
thread.$bindTo($scope, 'thread')
$scope.addComment= function(){
if(!$scope.newComment){
return false;
}
var currentUser = userService.getLoggedInUser();
var date = new Date();
var newComment = {
text: $scope.newComment,
username: currentUser.name,
dateAdded: date.getTime(),
userPic: currentUser.profilePic
};
$scope.thread.comments = $scope.thread.comments || [];
$scope.thread.comments.push(newComment);
$scope.thread.numComments += 1;
$scope.newComment = '';
}
});
Your code is referring to an Auth factory, which is shown in the example under Retrieving Authentication State. Include this in your code.
.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
var ref = new Firebase("<YOUR FIREBASE>");
return $firebaseAuth(ref);
}
]);
I have an angular controller called SubmissionTreeController and it has update_dashboard() function which refreshes the ui every minute.
My goal is to refresh the ui on successful post request from a different controller.
How do I make this function available in other controllers?
var module = angular.module("submissionDashboard", ['ui.tree', 'ngCookies', 'ui.bootstrap',]);
module.controller("SubmissionTreeController", ["$scope", "$http", "$modal",
function($scope, $http, $modal) {
$scope.selected_items = {};
var update_dashboard = function() {
var url = Django.url('submission:active_list_ajax', {
site : site
});
$http.get(url).success(function(data) {
$scope.list = data.results;
});
};
update_dashboard();
$scope.closeTask = function(scope) {
var modalInstance = $modal.open({
templateUrl: 'modal_close_submission_renderer.html',
controller: 'ModalCloseSubmissionController',
resolve: {
items: function () {
return $scope.selected_items;
}}
});
};
}]);
module.controller('ModalCloseSubmissionController', ['$scope', '$modalInstance', '$http', 'items', function ($scope, $modalInstance, $http, items) {
$scope.items = items;
$scope.selected = {
item: 1,
text: ''
};
$scope.ok = function () {
var val = $scope.selected.item;
if (val === 1) {
var url = Django.url('submission:close-notify', {
site : site
});
$http.post(url, $scope.selected_items).success(function(data) {
update_dashboard();
});
} else if (val === 2) {
var url = Django.url('submission:close', {
site : site
});
$http.post(url, $scope.selected_items).success(function(data) {
update_dashboard();
});
} else if (val === 3) {
var url = Django.url('submission:cancel', {
site : site
});
$http.post(url, $scope.selected_items).success(function(data) {
update_dashboard();
});
};
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);
Edit:
What I am trying to do:
module.service('updateDashboardService', function($scope, $http){
this.update_dashboard = function() {
$scope = $scope;
var url = Django.url('submission:active_list_ajax', {
site : site
});
$http.get(url).success(function(data) {
$scope.list = data.results;
});
};
});
module.controller("SubmissionTreeController", ["$scope", "$http", "$modal", "updateDashboardService", function($scope, $http, $modal, updateDashboardService) {
$scope.selected_items = {};
updateDashboardService.update_dashboard();
var timer = setInterval(function() {
$scope.$apply(updateDashboardService.update_dashboard($scope, $http));
}, 1000 * 60);
What I am getting:
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- updateDashboardService
Edit 2:
module.service('updateDashboardService', function($rootScope, $http){
this.update_dashboard = function() {
var url = Django.url('submission:active_list_ajax', {
site : site
});
$http.get(url).success(function(data) {
$rootScope.list = data.results;
});
};
});
As #Gopesh says create a factory method, or, you can do something like this in SubmissionTreeController:
$scope.$on("event:updateDashboard", function(){ update_dashboard() });
And in your other controller:
$http.post(url, $scope.selected_items).success(function(data) {
$scope.$emit("event:updateDashboard");
});