AMQJS0005E Internal error. Error Message: Cannot read property 'subscribe' of undefined
I included eclipse paho javascript client library in my app.
connection is established but, I cannot subscribe to a topic.
here is the code that I used..
import { Component } from '#angular/core';
import { NavController, NavParams ,MenuController } from 'ionic-angular';
import { Setuser } from '../../providers/setuser';
import { Platform } from 'ionic-angular';
import { Paho} from 'ng2-mqtt/mqttws31';
/*
Generated class for the Usershome page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-usershome',
templateUrl: 'usershome.html'
})
export class UsershomePage {
client :any;
message :any;
constructor(public navCtrl: NavController, public navParams: NavParams,public menu:MenuController,public setUserProvider: Setuser,public platform:Platform) {
this.menu.open();
}
ionViewDidLoad() {
this.menu.enable(true);
console.log('ionViewDidLoad UsershomePage');
}
exitApp(){
console.log("----------");
this.platform.exitApp();
}
connectToMqtt(){
this.client = new Paho.MQTT.Client("test.mosquitto.org",8080,"abc");
// set callback handlers
this.client.onConnectionLost = this.onConnectionLost;
this.client.onMessageArrived = this.onMessageArrived;
// connect the client
this.client.connect({onSuccess:this.onConnect});
}
// called when the client connects
onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
this.client.subscribe("mitsuruog");
this.message = new Paho.MQTT.Message("Hello");
this.message.destinationName = "World";
this.client.send(this.message);
}
// called when the client loses its connection
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
// called when a message arrives
onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
}
Your immediate problem is solvable by modifying the line
this.client.connect({onSuccess:this.onConnect.bind(this)});
or, surprisingly for you, by removing all this. in front of client and message references.
You should learn what exactly means this in JavaScript. Not the same thing as in Java or C#. To understand why the removal works, learn about closures and arrow functions.
Good starting point (your question could be actually flagged as duplicate of this one):
How to access the correct `this` context inside a callback?
Related
Consider the following class:
enum LoginState { loggedOut, loggedIn }
class StreamListener {
final FirebaseAuth _auth;
LoginState _state = LoginState.loggedOut;
LoginState get state => _state;
StreamListener({required FirebaseAuth auth}) : _auth = auth {
_auth.userChanges().listen((user) {
if (user != null) {
_state = LoginState.loggedIn;
} else {
_state = LoginState.loggedOut;
}
});
}
}
I would like to test that when a user login the state changes from loggedOut to loggedIn, see the following test code:
class FakeUser extends Fake implements User {}
#GenerateMocks([FirebaseAuth])
void main() {
StreamController<User?> controller = StreamController<User?>();
final User value = FakeUser();
setUp(() {
controller = StreamController.broadcast();
});
tearDown(() {
controller.close();
});
test('Stream listen test', () {
final MockFirebaseAuth mockAuth = MockFirebaseAuth();
when(mockAuth.userChanges()).thenAnswer((_) => controller.stream);
StreamListener subject = StreamListener(auth: mockAuth);
controller.add(value);
expect(subject.state, LoginState.loggedIn);
});
}
However, due to the async behaviour the login state is still loggedOut. How could I test this properly?
I don't think that you can test that in a way that is strictly correct. Your StreamListener class promises to update state in response to Stream events, but it's asynchronous, you have no formal guarantee when those updates might happen, and you have no way to notify callers when those updates eventually do occur. You could solve that by modifying StreamListener to provide a broadcast Stream<LoginState> that is emitted whenever _state changes.
From a practical perspective of being good enough, there are a few things you could do:
Rely on Dart's event loop to invoke all of the Stream's listeners synchronously. In other words, after adding an event to your Stream, allow Dart to return the event loop so that the Stream's listeners can execute:
test('Stream listen test', () async {
...
StreamListener subject = StreamListener(auth: mockAuth);
controller.add(value);
await Future<void>.value();
expect(subject.state, LoginState.loggedIn);
Since you are using a broadcast Stream, you alternatively could rely on multiple Stream listeners firing in order of registration. (I don't see any formal documentation guaranteeing that ordering, but I think it is the sanest behavior.) Your test could register its own listener after your object has registered its listener, use expectAsync1 to verify that the test's listener is called, and have the test's listener verify the state of your object:
StreamListener subject = StreamListener(auth: mockAuth);
controller.stream.listen(expectAsync1((event) {
expect(event, value);
expect(subject.state, LoginState.loggedIn);
}));
controller.add(value);
Or combine the approaches:
test('Stream listen test', () async {
...
var eventReceived = Completer<void>();
StreamListener subject = StreamListener(auth: mockAuth);
controller.stream.listen((_) => eventReceived.complete());
controller.add(value);
await eventReceived.future;
expect(subject.state, LoginState.loggedIn);
As described here, I have implemented the authorization:
start/bouncer.ts:
import Bouncer from '#ioc:Adonis/Addons/Bouncer'
export const { actions } = Bouncer
export const { policies } = Bouncer.registerPolicies({
UserPolicy: () => import('App/Policies/UserPolicy'),
})
app/Policies/UserPolicy.ts:
import { BasePolicy } from '#ioc:Adonis/Addons/Bouncer'
import User from 'App/Models/User'
export default class UserPolicy extends BasePolicy {
public async before(user?: User) {
return user?.isSuperUser
}
public async list(user: User) {
await user.load('policies')
return user.policies.some((policy) => policy.identifier === 'user:list')
}
// ...
}
resources/vires/layouts/main.edge
#can('UserPolicy.list')
<p>Can see users list</p>
#endcan
And I cannot see the paragraph. In fact, I placed console.log inside the action, but it didn't get executed. I don't know if I'm missing anything. Can anyone shed some lights onto it?
Gotcha! This says:
The actual action callback is never executed when a before hook returns a true or a false value.
Make sure to return undefined if you want the bouncer to execute the next hook or the action callback.
These 2 statements were missed out. :)
I used a simple statement like below to access headers in loopback4.
console.log(request.headers);
But it is printing undefined. A sample request headers that I want to access is in the image.
request header image
I am receiving the request and its headers which is perfectly fine. It's just that I am not able to access its headers as I am getting undefined from request.headers.
I am a beginner in loopback so pls explain it.
If i have to use a bodyparser then how i would have to use it in loopback4 because it is different from express.
Update
The original answer, although valid, is not the recommended way. Use dependency injection instead:
import {inject} from '#loopback/core';
import {get, param} from '#loopback/rest';
export class SomethingController {
constructor() {}
#get('/something')
something(#param.header.string('x-your-header') yourHeader: string): void {
// Use your header.
// e.g. Log to console
console.log(yourHeader);
}
}
Unlike the REQUEST object, this strips away unnecessary info and provides built-in coercion.
Further reading
https://loopback.io/doc/en/lb4/Decorators_openapi.html#parameter-decorator
https://loopback.io/doc/en/lb4/apidocs.openapi-v3.param.html
Original answer
If you're attempting to access the headers in a Controller, then you can inject the REQUEST object:
import {inject} from '#loopback/core';
import {get, Request, RestBindings} from '#loopback/rest';
export class SomethingController {
constructor(#inject(RestBindings.Http.REQUEST) private req: Request) {}
#get('/something')
something(): void {
// Get the headers
this.req.headers;
}
}
You can also use Context, example
import {inject} from '#loopback/core';
import {
post, RequestContext
} from '#loopback/rest';
export class UserController {
constructor(
#inject.context()
public context: RequestContext,
) {}
#post('/users/logout', {
responses: {
'200': {
description: 'Return success',
content: {
'application/json': {
schema: {
type: 'object'
},
},
},
},
},
})
async logout(): Promise<object> {
// ensure the token exists
const authHeader = this.context.request.headers.authorization;
if(authHeader && authHeader.split(" ")[1]){
// remove token
return {code:204, status: true, message:'Logout successful'};
}else{
return {code: 404, status: false, message:'Something went wrong'};
}
}
}
In sequence.ts, request object is called via context.
const {request, response} = context;
console.log(request.headers)
add log in sequence.ts to get the request headers.
I am new to web3.js and solidity. My question is related to the way we search on the block-chain. Its easy to search for a particular contract if we know the contract address. However, how can we find and identify a specific type of contract using the from address used to create the contracts in the first place.
For eg.
I have a contract ContractA which is created by 'from' address AddressA using web3.js. Now I want to find all the instances of ContractA created by AddressA.
I tried searching using web3.eth.filter API but noting ever returns. Please help.
I also read about using registry pattern to store all the contracts and ask the registry, but couldn't find any useful example.
For those who are looking for a way, as Adam said in his post, there is no direct way to find contracts created by wallet address. Hence, we have to implement registry pattern as shown below to keep track of things and just ask that contract in web3.js, also shown below....
This is how my contract look like
contract ContractA {
bool public is_approved;
address public visa_details;
uint public artifact_count;
// constructors
function ContractA() public {
owner = msg.sender;
}
}
Here is the registry pattern contract
contract ContractARegistry {
mapping(address => address[]) user_contracts;
function registerContract(address contractA) public {
user_applications[msg.sender].push(contractA) - 1; // -1 is very important
}
function findContract(address user) view public returns (address[]){
return user_contracts[user];
}
}
In web3.js you may search like this (I am using Angular4)
import * as ContractA from '../../../../build/contracts/ContractA.json';
import * as UserContracts from '../../../../build/contracts/UserContracts.json';
import * as TruffleContract from 'truffle-contract';
import {Observable} from "rxjs/Observable";
declare var window: any;
#Injectable()
export class AppWeb3ContractAService {
CONTRACT_A = TruffleContract(ContractA);
USER_CONTRACTS = TruffleContract(UserContracts);
constructor(private appWeb3Svc: AppWeb3Service) {
console.log("Injecting the provider");
this.CONTRACT_A.setProvider(this.appWeb3Svc.currentProvider());
this.USER_CONTRACTS.setProvider(this.appWeb3Svc.currentProvider());
}
create(ethAddress): Observable<any> {
return Observable.create(observer => {
this.CONTRACT_A
.new({
from: ethAddress
})
.then(application => {
this.USER_CONTRACTS
.deployed()
.then(registry => {
registry.registerContractA(application.address, {from: ethAddress})
.then(result => observer.next(application))
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
});
}
findAll(ethAddress: string):
Observable<any[]> {
return Observable.create(observer => {
this.USER_CONTRACTS
.deployed()
.then(registry => {
registry.findUserContracts(ethAddress, {from: ethAddress})
.then(addresses => {
addresses.forEach(address => observer.next(this.CONTRACT_A.at(address)));
})
.catch(error => observer.error(error));
})
.catch(error => observer.error(error));
});
}
}
This is how my appWeb3Svc looks like
import {Injectable} from '#angular/core';
import {environment} from '../../../environments/environment';
import * as Web3 from 'web3';
declare var window: any;
#Injectable()
export class AppWeb3Service {
public web3: Web3;
checkAndInstantiateWeb3 = () => {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof window.web3 !== 'undefined') {
console.warn(
'Using web3 detected from external source. If you find that your accounts don\'t appear or you have 0 MetaCoin, ensure you\'ve configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask'
);
// Use Mist/MetaMask's provider
this.web3 = new Web3(window.web3.currentProvider);
} else {
console.warn(
'No web3 detected. Falling back to ${environment.HttpProvider}. You should remove this fallback when you deploy live, as it\'s inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask'
);
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
this.web3 = new Web3(
new Web3.providers.HttpProvider(environment.HttpProvider)
);
}
};
constructor() {
this.checkAndInstantiateWeb3();
}
currentProvider() {
return this.web3.currentProvider;
}
eth() {
return this.web3.eth;
}
isAddress(ethAddress: string): boolean {
if (this.web3) {
return this.web3.isAddress(ethAddress);
}
return false
}
}
Hope this helps!
Unfortunately, there's no easy way to do this exact thing. web3.eth.filter can be used to apply filters on contract address, or they can be used to search across transaction logs (events emitted by a contract) where the sender is in the topic list.
If you want all transactions submitted by a specific address, you pretty much have to traverse each block on the chain and examine each transaction within each block to see if from is set to the address you're interested in.
// while looping through the block numbers you're interested in
web3.eth.getBlock(blockNum, (err, block) => {
if (block != null) {
block.transactions.forEach(tx => {
if (tx.from === myAddress) {
// Do something
}
}
}
});
I'm trying to use ionic native's media plugin like this:
record(){
...
return this.media.create(src,onStatusUpdate).then((mediaObj) => {
mediaObj.startRecord();
return mediaObj;
});
}
And I use the mediaObj returned from it elsewhere, but I also need to know the status of the mediaObj; this apparently comes from passing a second argument, a callback function, to the media.create() function. However, I don't know how to get the mediaObj's status in there. I know the following would work for just telling me the status, but I actually need to access it.
const onStatusUpdate = (status) => console.log(status);
So, the question is, is there a way to simply access the mediaObj's status?
The MediaPlugin status update notification is all you get so set a class property with the value you get when the status change.
To manage the MediaObject I set a property to the value obtained when the promise is resolved.
import { ApplicationRef } from '#angular/core';
...
...
export class PlayerPage {
track:any;
file:MediaObject = undefined;
position:any = undefined;
status:any = 0;
constructor(public ref ApplicationRef, public navCtrl: NavController, private navParams: NavParams, public AppstateProvider: Appstate, private media: MediaPlugin) {
this.track = navParams.get('track');
media.create('http://.../...mp3',(status)=>{
this.status = status;
this.ref.tick();
}).then((file: MediaObject) => {
this.file = file;
});
}
play() {
this.file.play();
}
The this.ref.tick(); is necesarry because Angular does not detect this property update - I tried publishing and subscribing Angular still did not detect the property update.