$log anonymous function angular js not working - javascript

I have a problem when I try to log some data inside the function of webtorrent.
I want to log some values of this.client.add but I don't have access.
Some idea of what's going on here?
import Webtorrent from 'webtorrent';
class PlaylistController {
/** #ngInject */
constructor($http, $log) {
this.log = $log;
this.client = new Webtorrent();
$http
.get('app/playlist/playlist.json')
.then(response => {
this.Torrent = response.data;
});
}
addTorrent(magnetUri) {
this.log.log(magnetUri);
this.client.add(magnetUri, function (torrent) {
// Got torrent metadata!
this.log.log('Client is downloading:', torrent.infoHash);
torrent.files.forEach(file => {
this.log(file);
});
});
this.log.log('sda');
this.log.log(this.client);
}
}
export const playlist = {
templateUrl: "app/playlist/playlist.html",
controller: PlaylistController,
bindings: {
playlist: '<'
}
};
Another thing its I use yeoman for the scaffold of my app and its has JSLint with console.log forbidden and its said that you must use angular.$log, but the thing its I don't wanna change that, I wanna understand the problem here.

You either need to refer to this (the class) as another variable to use inside the function(torrent) function or use arrow functions so that this reference remains the class one.
Solution 1, using another variable to ref the class:
addTorrent(magnetUri) {
this.log.log(magnetUri);
var that = this;
this.client.add(magnetUri, function (torrent) {
// Got torrent metadata!
that.log.log('Client is downloading:', torrent.infoHash);
torrent.files.forEach(file => {
that.log(file);
});
});
this.log.log('sda');
this.log.log(this.client);
}
Solution 2, using arrow functions:
addTorrent(magnetUri) {
this.log.log(magnetUri);
this.client.add(magnetUri, torrent => {
// Got torrent metadata!
this.log.log('Client is downloading:', torrent.infoHash);
torrent.files.forEach(file => {
this.log(file);
});
});
this.log.log('sda');
this.log.log(this.client);
}

Related

Cannot read values from file in fixture folder, getting error as "TypeError Cannot read properties of undefined (reading 'data')"

I'm trying to use fixtures to hold data for different tests, specifically user credentials. This is an example of the code. I'm getting 'Cannot read properties of undefined (reading 'data')'. I tried to google search , I found Cypress fixtures - Cannot read properties of undefined (reading 'data')
I used closure variable technique as reccomended in that post , yet I got reference error of unable to reference data.Please help me.I know cypress.config can be used but I want to keep that for global configs
Json(credentials.json):
{
"username":"*****",
"password":"*****"
}
Code:
import { LoginPage } from "./pageobject/login_page"
describe('Test Scenario', () => {
before(function () {
cy
.fixture('credentials').then(function (data) {
this.data = data
})
})
it('Simple login', () => {
cy.visit(Cypress.env('url'))
var loginpage = new LoginPage()
loginpage.EnterUsername(this.data.username)
loginpage.clickonSubmit()
loginpage.EnterPassword(this.data.password)
loginpage.clickonSubmit()
Cypress
.on('uncaught:exception', (err, runnable) => {
return false;
});
cy.
wait(10000)
cy.
get('span[id="user"]').should('have.text', this.data.username , 'User Login Unsuccessfully')
});
});
There's a few things need adjusting
use function () {} syntax in the it() block
use beforeEach() and alias to load the fixture, because data on this can be cleared (especially after login)
move uncaught:exception catcher to the top of the block
don't cy.wait(), instead add timeout to next command
.should() only has two parameters in this case, so use .and() to test the 2nd text
import { LoginPage } from './pageobject/login_page';
describe('Test Scenario', () => {
beforeEach(function () {
cy.fixture('credentials').as('data')
})
it('Simple login', function() {
Cypress.on('uncaught:exception', (err, runnable) => {
return false;
});
cy.visit(Cypress.env('url'));
var loginpage = new LoginPage();
loginpage.EnterUsername(this.data.username);
loginpage.clickonSubmit();
loginpage.EnterPassword(this.data.password);
loginpage.clickonSubmit();
cy.get('span[id="user"]', {timout:10_000})
.should('have.text', this.data.username)
.and('have.text', 'User Login Unsuccessfully')
})
})
I suspect it's because you are using an arrow function instead of a regular function, you cannot access the this object with an arrow function.
Cypress docs
If you store and access the fixture data using this test context
object, make sure to use function () { ... } callbacks. Otherwise the
test engine will NOT have this pointing at the test context.
change it to this:
it('Simple login', function() {
...
});

Connect to SignalR Hub after connection start

Let's say i have two or more hubs in my server application. My javascipt client (Angular SPA) initialy needs a connection to the first hub, and needs to subscribe to a method like this:
connection = $.hubConnection(appSettings.serverPath);
firstHubProxy = connection.createHubProxy('firstHub');
firstHubProxy('eventFromFirstHub', function () {
console.log('Method invokation from FirstHub');
});
connection.start().done(function (data) {
console.log("hub started");
});
Everything is working fine. Now a user of my Angular SPA may decide to put a widget on his page, which needs to subcribe to a method from the second hub:
secondHubProxy = connection.createHubProxy('firstHub');
secondHubProxy('eventFromSecondHub', function () {
console.log('Method invokation from SecondHub');
});
The method from the second hub is not working. I guess because it was created after connection.start().
My example is simplified, in my real appplication there will be 20+ hubs to which users may or may not subscribe by adding or removing widgets to their page.
As far as i can tell i have two options:
call connection.stop() and then connection.start(). Now both hub subscriptions are working. This just doesn't feel right, because on all hubs, the OnConnected() event fires, and my application will be starting and stopping all the time.
create hub proxy objects for all possible hubs, subscribe to a dummy
method on all possible hubs, so the application can subscibe to hub
methods later if desired. This also doesn't feel right, because i
need to create 20+ hub proxies, while i may need just a few of
those.
Is anybody aware of a pattern which i can use to accomplish this? Or am i missing something very simple here?
Personally I use #2. I have a hub service that subscribes to all client methods. Any of my other angular components then pull that hub service in and subscribe to its events as needed.
Here it is;
hub.js
(function () {
'use strict';
angular
.module('app')
.factory('hub', hub);
hub.$inject = ['$timeout'];
function hub($timeout) {
var connection = $.connection.myHubName;
var service = {
connect: connect,
server: connection.server,
states: { connecting: 0, connected: 1, reconnecting: 2, na: 3, disconnected: 4 },
state: 4
};
service = angular.extend(service, OnNotify());
activate();
return service;
function activate() {
connection.client.start = function (something) {
service.notify("start", something);
}
connection.client.anotherMethod = function (p) {
service.notify("anotherMethod", p);
}
// etc for all client methods
$.connection.hub.stateChanged(function (change) {
$timeout(function () { service.state = change.newState; });
if (change.state != service.states.connected) service.notify("disconnected");
console.log("con:", _.invert(service.states)[change.oldState], ">", _.invert(service.states)[change.newState]);
});
connect();
}
function connect() {
$.connection.hub.start({ transport: 'auto' });
}
}
})();
OnNotify
var OnNotify = function () {
var callbacks = {};
return {
on: on,
notify: notify
};
function on(name, callback) {
if (!callbacks[name])
callbacks[name] = [];
callbacks[name].push(callback);
};
function notify(name, param) {
angular.forEach(callbacks[name], function (callback) {
callback(param);
});
};
}
Then I can subscribe to things as needed, for example in a controller;
(function () {
'use strict';
angular
.module('app')
.controller('MyController', MyController);
MyController.$inject = ['hub'];
function MyController(hub) {
/* jshint validthis:true */
var vm = this;
vm.something = {};
hub.on('start', function (something) {
$timeout(function () {
console.log(something);
vm.something = something;
});
});
}
})();

Angular-Toaster not working in my service?

I have got to know toaster.js from this site and trying to implement it in my web app. I have done it according to the example but it doesn't work.
Here is my service where I Implemented:
function () {
angular
.module('FoursquareApp')
.factory('DataService', DataService);
DataService.$inject = ['$http','toaster'];
function DataService($http, toaster) {
.id,
venueName: venue.name,var serviceBase = '/api/places/';
var placesDataFactory = {};
var userInContext = null;
var _getUserInCtx = function () {
return userInContext;
};
var _setUserInCtx = function (userInCtx) {
userInContext = userInCtx;
};
var _savePlace = function (venue) {
//process venue to take needed properties
var minVenue = {
userName: userInContext,
venueID: venue
address: venue.location.address,
category: venue.categories[0].shortName,
rating: venue.rating
};
return $http.post(serviceBase, minVenue).then(
function (results) {
toaster.pop('success', "Bookmarked Successfully", "Place saved to your bookmark!");
},
function (results) {
if (results.status == 304) {
toaster.pop('note', "Faield to Bookmark", "Something went wrong while saving :-(");
}
else {
toaster.pop('error', "Failed to Bookmark", "Something went wrong while saving :-(");
}
return results;
});
};
I have called the library scripts in index.html and also the css files.
Any ideas of what I might be doing wrong?
Are you sure that you use toaster.js library? The popular one is toastr.js
Try to modify your code to
DataService.$inject = ['$http','toastr'];
function DataService($http, toastr) {
...
Also ensure, that you link this js file in you index.html and also refer this package in main app module definition as a second (dependency) parameter

AngularJS tutorial Thinkster.io chapter 7

UPDATE: The tutorial was updated and the following question really no longer applies
Learning about AngularJS from the site thinkster.io (free ebook). But at the moment i'm stuck at chapter 7 - Creating your own user data using firebase. This is an tutorial about angularjs that works with firebase.
I have wrote all the code according to the site, but i'm getting these console errors when I want to register a user. It will create the user (in firebase -simplelogin), but not the user object (in firebase - data).:
TypeError: undefined is not a function
at Object.User.create (http://localhost:9000/scripts/services/user.js:46:19)
at http://localhost:9000/scripts/controllers/auth.js:32:22
etc.
This is the code (same as the site), the error is in the create() function and talks about the users.$save() function, snippet of User.create():
users.$save(username).then(function () {
setCurrentUser(username);
});
Complete code of user.js:
news.factory("User", function ($firebase, FIREBASE_URL, $rootScope, $log) {
var reference, users, User;
reference = new Firebase(FIREBASE_URL + "users");
users = $firebase(reference);
function setCurrentUser(username) {
$rootScope.currentUser = User.findByUsername(username);
}
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference.startAt(authUser.uid).endAt(authUser.uid));
query.$on("loaded", function () {
setCurrentUser(query.$getIndex()[0]);
});
});
$rootScope.$on("$firebaseSimpleLogin:logout", function () {
delete $rootScope.currentUser;
});
User = {
create: function (authUser, username) {
users[username] = {
md5_hash: authUser.md5_hash,
username: username,
"$priority": authUser.uid
};
$log.debug(users);
users.$save(username).then(function () {
setCurrentUser(username);
});
},
findByUsername: function (username) {
if (username) {
return users.$child(username);
}
},
getCurrent: function () {
return $rootScope.currentUser;
},
signedIn: function () {
return $rootScope.currentUser !== undefined;
}
};
return User;
});
Edit 1:
Registering a user now works, got it working (saving in firebase, simple login and data):
users = $firebase(reference).$asObject();
Notice the users.save() function:
create: function (authUser, username) {
users[username] = {
md5_hash: authUser.md5_hash,
username: username,
$priority: authUser.uid
};
$log.debug(users);
users.$save().then(function () {
setCurrentUser(users);
});
},
findByUsername: function (users) {
if (users) {
return users;
}
},
Edit 2:
Now I get an error at the log in of the user (see below), when I want to log in, I get an error on this this function, query.$on():
TypeError: undefined is not a function
at http://localhost:9000/scripts/services/user.js:26:19
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference.startAt(authUser.uid).endAt(authUser.uid));
query.$on("loaded", function () {
setCurrentUser(query.$getIndex()[0]);
});
});
What is wrong now?
This is an answer on edit 2: I have used firebase(ref), query.$loaded and searched for the right object, that's it. Maybe someone have an different answer, please post them :).
I have finally completed chapter 07!
In general (solution for Edit 2):
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference).$asObject();
query.$loaded(function (result) {
angular.forEach(result, function (key) {
if (key.md5_hash === authUser.md5_hash) {
setCurrentUser(key);
}
});
});
});
This is not the ideal solution, but the free ebook (atm of writing) is far from ideal. Then again, these kind of situations helps you to understand a little bit more about the firebase api and how it works with angular. But can be frustrated at times, when you just want to go through the tutorial ;).
Note! I have saved the User object and pass the User object to the findUsername() and setCurrentUser() functions instead of just the user.username.
You can also use the native array function, like some().
I think your system uses the newer version of Angularfire (version>= 0.8). Which means for running through loops that are arrays ...you need to attach .$asArray() at the end of the user definition field. Check the updates of Firebase.

Function statement requires a Name in Services in AngularJS

I am building a demo app. I want this AngularJS app to have factory as well.
I keep getting error: "SyntaxError: function statement requires a name"
Below is my code:
var bookApp = angular.module('bookAppModule',[]);
bookApp.controller('boookbAppCtrl', ['$scope','$http',Book ,
function($scope,$http,Book) {
$scope.way=["Normal","$http","RestFul"];
$scope.books =
[
{"title":"abc","author":"zxc"},
{"title":"def","author":"cvb"},
{"title":"ghi","author":"nml"},
{"title":"jkl","author":"kjh"},
{"title":"mno","author":"fds"}
];
var names=["Anuj","Donvir"];
$scope.newbooks = Book.getBooks;
}]);
bookApp.factory('Book',
function(){
getBooks : function(){
return
[
{"title":"newbook1","author":"zxc"},
{"title":"newbook2","author":"cvb"},
{"title":"newbook3","author":"nml"},
{"title":"newbook4","author":"kjh"},
{"title":"newbook5","author":"fds"}
];
}
});
In your factory, you forgot to write the overall return function that returns all the 'methods' in the service.
bookApp.factory('Book',
function(){
return { // you did not have this return, only its body
getBooks : function(){
return
[
{"title":"newbook1","author":"zxc"},
{"title":"newbook2","author":"cvb"},
{"title":"newbook3","author":"nml"},
{"title":"newbook4","author":"kjh"},
{"title":"newbook5","author":"fds"}
];
}
}
});
Addition
Also, to add on the above reason which caused the error, personally i battled for many days with a similar error in angular services. It was caused by the overall return function not being in the same line with the { that contains the body of the return. See below.
// will cause the error
bookApp.factory('Book',
function(){
return
{ // { below not on same line with return
getBooks : function(){
// ...
}
}
});
// will not cause the error
bookApp.factory('Book',
function(){
return { // { on same line with return
getBooks : function(){
// ...
}
}
});
I do not know the exact reason for this behaviour but what i know is that when you use them on same line, it will work and you will not have to stall your project like i did many times.
If you need to forget the position of the braces, you can define this angular factory using Revealing Module Pattern as like this...
bookApp.factory('Book',
function(){
var factoryServices=
{
getBooks: getBooks
};
return factoryServices;
function getBooks()
{
// ...
}
}
});
For more reading: https://github.com/johnpapa/angular-styleguide#style-y052

Categories

Resources