Using hello.js with React.js - reactjs

I'd like to understand how to make Hello.js work with React.js , especially the custom event handler hello.on
As I'm new to React.js, I don't understand how to bind non React events into the app flow.
I tried putting the event handler in the componentDidMount handler
handleClick(){
hello('twitter').login();
}
componentDidMount(){
hello.on('auth.login', function(auth) {
// Call user information, for the given network
hello(auth.network).api('/me').then(function(r) {
console.log(r);
});
});
hello.init({
'twitter' : 'J1jqqO50tcLtLx8Js0VDitjZW'
},
{
redirect_uri:'/',
oauth_proxy: 'https://auth-server.herokuapp.com/proxy'
});
}
thanks

And 3 years later:
You need a class for authentication, for example:
import * as React from "react";
import * as hello from "hellojs";
import { Event } from "../interfaces/Event";
export class Authentication extends React.Component<{}, { sendEvent: boolean }> {
constructor(public props, public context) {
super(props, context);
this.state = {
sendEvent: true
};
}
public login(network) {
hello.init({
aad: {
name: "Azure Active Directory",
oauth: {
version: 2,
auth: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
grant: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
},
// Authorization scopes
scope: {
// you can add as many scopes to the mapping as you want here
profile: "user.read",
offline_access: ""
},
scope_delim: " ",
login: p => {
if (p.qs.response_type === "code") {
// Let's set this to an offline access to return a refresh_token
p.qs.access_type = "offline_access";
}
},
base: "https://www.graph.microsoft.com/v1.0/",
get: {
me: "me"
},
xhr: p => {
if (p.method === "post" || p.method === "put") {
JSON.parse(p);
} else if (p.method === "patch") {
hello.utils.extend(p.query, p.data);
p.data = null;
}
return true;
},
// Don't even try submitting via form.
// This means no POST operations in <=IE9
form: false
}
});
hello.init(
{
aad: "ClientID"
},
{
redirect_uri: "YOUR REDIRECT_URI",
//redirect_uri: 'https://localhost:4321/temp/workbench.html',
scope: "user.read"
}
);
// By defining response type to code, the OAuth flow that will return a refresh token to be used to refresh the access token
// However this will require the oauth_proxy server
hello(network)
.login({ display: "none" })
.then(
authInfo => {
console.log(authInfo);
localStorage.setItem("logged", authInfo.authResponse.access_token);
},
e => {
console.error("Signin error: " + e.error.message);
}
);
}
//when the component is mounted you check the localstorage
//logged ==> undefined you call login and save a token in localstorage
//logged ==> with a token -> setEvent call a function that use graph api
public componentDidMount() {
let logged = localStorage["logged"];
if (logged === undefined) this.login("aad");
else {
if (this.state.sendEvent) {
this.props.setEvent(null);
this.props.setEvent(Event.GET_ALL_USERS);
}
}
}
public render() {
return null;
}
}
the file name is auth.tsx and you can call this class in the main react class:
export class mainClass extends React.Component{
......
......
private getEvent = (event) => {
this.setState({ event: event });
//HERE YOU recive the event when auth is ready
}
public render(){
<Authentication setEvent={this.getEvent} />
}
}

Related

can't append to sourceBuffer because mediaSource Element (Parent) was removed

I'm having problem with video Streaming.
I'm using socket io for video Streaming and react for front end.
Front End code looks like this:-
class VideoElement extends React.Component {
constructor(props) {
/* props is having Id, projectDesignSocket */
super();
this.state = { hasError: false };
this.videoRef = React.createRef();
this.mediaSource = null;
this.sourceBuffer = null;
}
componentDidMount() {
this.mediaSource = new MediaSource();
this.videoRef.current.src = URL.createObjectURL(this.mediaSource);
this.mediaSource.onsourceopen = (e) => {
URL.revokeObjectURL(this.videoRef.current.src);
this.sourceBuffer = this.mediaSource.addSourceBuffer("video/webm; codecs=\"vp8, opus\"");
this.sourceBuffer.mode = 'sequence';
this.props.projectDesignSocket.on(`${this.props.Id}VideoData`, ({ blob }) => {
try {
this.sourceBuffer.appendBuffer(blob);
}
catch (err) {
console.log(err);
}
finally {
console.log(this.sourceBuffer);
}
});
}
}
render() {
if (this.state.hasError) {
return <h1>error</h1>;
}
else {
return <video autoPlay ref={this.videoRef} id={this.props.Id}></video>;
}
}
componentWillUnmount() {
this.mediaSource.onsourceopen = null;
this.props.projectDesignSocket.off(`${this.props.Id}VideoData`);
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.log(error, info);
}
}
class VideoConfrence extends React.Component {
/* prop is having projectDesignSocket, isAdmin, userList, currentRoom, userName, userId */
constructor(props) {
super();
this.state = {};
this.userVideoRef = React.createRef();
this.mediaRecorder = null;
this.videoStream = null;
}
static getDerivedStateFromProps(nextProp, prevState) {
if (nextProp.userList !== prevState.userList) {
return { userList: nextProp.userList }
}
else {
return {};
}
}
componentDidMount() {
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(stream => {
this.videoStream = stream;
this.userVideoRef.current.srcObject = stream;
this.mediaRecorder = new MediaRecorder(stream);
this.mediaRecorder.start(100);
this.mediaRecorder.ondataavailable = (e) => {
if (e.data.size) {
this.props.projectDesignSocket.emit('video', {
room: this.props.currentRoom,
data: { userId: this.props.userId, blob: e.data }
});
}
}
}).catch(err => {
console.log(err);
});
}
render() {
return (
<div className='videoConfrencing'>
<video autoPlay ref={this.userVideoRef} />
{
this.state.userList.map((item, index) => {
if (item !== this.props.userId) {
return <VideoElement key={index} Id={item} projectDesignSocket={this.props.projectDesignSocket} />
}
else {
return null;
}
})
}
</div>
);
}
componentWillUnmount() {
this.videoStream.getTracks().forEach(function (track) {
track.stop();
});
this.mediaRecorder.ondataavailable = null;
this.props.projectDesignSocket.off('newMemberAdded');
}
}
And Backend Like This :-
socket.on('video', function ({ room, data }) {
// data has userid and blob as it's properties
if (room && data ) {
socket.broadcast.to(room).emit(`${data.userId}VideoData`, {blob:data.blob});
}
})
error is occuring at try/catch block of componentDidMount of VideoElement
err:-Media resource blob:http://localhost:3000/493042c5-431b-40a1-aff6-5fafe218a677 could not be decoded, error: Error Code: NS_ERROR_FAILURE (0x80004005)
basicaly i'm designing an app for video confrencing and,
i've used mediaRecorder to record stream obtained by getUserMedia into Blobs and send those blobs to server throgh socket ('video event')
and the server receives roomName from which event was emmited, userId and blob of video and broadcast an event ${userId}VideoData to the specific room
when a user connects the server start receiving blobs and start broadcasting event ${userId}VideoData with {userId, blob} as values to be passed to client
when another user connects his webcam feeds are also sent to server...the user connected before him receives his video blobs and is able to play them , this user also receives video blobs of previously connected user but is unable to play them , on first append to sourceBuffer above warning is logged after which if appended again error is thrown!!
the error is that user which connects cant see the video of other users which were connected before him but is able to see the video of users connected after him!!
but users connected before him are able to see his video without any error

how to get data from DB using axios

I’m having a problem.
i have list of project i want when i click in one project he take me to another page(components) this is the component ProjectDetail when i can find the detail of that project Inside of it, I have this block of code:
this is the route who take me to another components:
{path: '/detail/:id', name: detail , component: detail },
I want to get the project with the id in the url detail from DB w but nothing Happen this is ProjectDetail.vue:
export default {
data(){
return{
id: this.$route.params.id,
projets:[],
projet:{
id:'',
name:'',
durre:'',
description:'',
budget:'',
owner:'',
}
}
},
methods:{
afficherProjets(){
axios.get('api/getProjects/'+this.id)
.then(data => {
this.projets = data.data;
});
}
},
mounted() {
console.log('Component mounted.')
this.afficherProjets();
}
}
and this is my controller:
public function getProjects($id)
{
return Projet::findOrFail($id);
}
in your vue.
export default {
data(){
return{
id: this.$route.params.id,
projet:{}
}
},
methods:{
//GETID
afficherProjet(){
axios.get('api/getProject/'+this.id)
.then(data => {
this.projet = data.data;
});
}
},
mounted() {
console.log('Component mounted.')
this.afficherProjet();
}
File in routes api.php
//ALL
Route::get('getProjects', ['uses' =>'API\ProjetController#getProjects']);
//SPECIFIQ ID
Route::get('getProject/{id}', ['uses' =>'API\ProjetController#getProject']);
In your controller, app/Http/API/ProjetController
public function getProjects()
{
return Projet::latest()->paginate(15);
}
public function getProject($id)
{
return Projet::findOrFail($id);
}
Your model projet
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Projet extends Model
{
public $timestamps = false;
protected $table = 'projets';
protected $fillable = [
'name',
'durre',
'description',
'budget',
'owner'
];
}
Do you have your model?
Your error comes from the 'data.data' i thing it's empty, you should just call 'data'.
Personally i prefer Mounted.
I thing now it's working!

Angular: data retrieved from API only appears when app is first time launched

I just have two components, and the app is connected to firebase (firestore). The data called in ngOnInit disappears when I navigate and only appears again if I insert a Post or a User (forms).Why? Can someone help me out?
The routes:
const routes: Routes = [
{ path: "", component: HomeComponent, pathMatch: "full" },
{
path: "admin",
component: AdminComponent
},
{
path: "**",
redirectTo: "/",
pathMatch: "full"
}
];
The Service
itemsCollection: AngularFirestoreCollection<Post>;
items: Observable<Post[]>;
itemDoc: AngularFirestoreDocument<Post>;
constructor(public afs: AngularFirestore) {
this.itemsCollection = this.afs.collection('posts', ref =>
ref.orderBy('date', 'desc')
);
this.items = this.itemsCollection.snapshotChanges().map(changes => {
return changes.map(a => {
const data = a.payload.doc.data() as Post;
data.id = a.payload.doc.id;
return data;
});
});
}
getItems() {
return this.items;
}
Its Component and the subscription
private postService: PostsService,
) {}
ngOnInit() {
this.postService.getItems().subscribe(data => {
this.postInput = data;
});
}
Create posts property in your service.
Then subscribe to your observable in your service, set posts to what u get from firebase.
Also dont write your code inside constructor but wrap in in a function and use it in OnInit in apropriate component. And lastly create a Subject send with it the current posts and subscribe to them in onInit inside desired components
posts = Post[]
postsChanged = new Subject<Post[]>()
getItems(){
this.itemsCollection.snapshotChanges().map(changes => {
return changes.map(a => {
return {
id: a.payload.doc.id,
...a.payload.doc.data()
}
}).subscribe(posts => {
this.posts = posts
this.postsChanged.next([...this.posts])
})
}
Based on Kase44 hints i managed to find a solution: wrapped the capture of the ID in a function, called it in the service constructor and in the ngOnInit():
The Service
export class UsersService {
usersCollection: AngularFirestoreCollection<Users>;
userDoc: AngularFirestoreDocument<Users>;
users: Observable<Users[]>;
user: Observable<Users>;
constructor(public afs: AngularFirestore) {
this.usersCollection = this.afs.collection('employees', ref =>
ref.orderBy('name', 'asc')
);
this.getUserID();
}
getUserID(){
this.users = this.usersCollection.snapshotChanges().map(changes => {
return changes.map(a => {
const data = a.payload.doc.data() as Users;
data.id = a.payload.doc.id;
return data;
});
});
}
And the component:
ngOnInit() {
this.userService.getUsers().subscribe(data => {
this.emp = data;
});
this.userService.getUserID();
}

Angular2 EventEmitter subscription does not work after navigate and come back

I emitted the data from MerchantComponent
and subscribed via EventEmitterService from MerchantPaymentChannelComponent, its OK when route directly opens this page. But you see there is other tabs which every tab has its own components. When I change the tab to different one, then come back to this MerchantPaymentChannelComponent its not subscribe again.
NOTE: I'm doing unsubscription on NgOnDestroy event
Here is codes;
MerchantListDetailService (SHARING SERVICE VIA EVENTEMITTER)
export class MerchantListDetailService {
#Output() emittedMerchant: EventEmitter<any> = new EventEmitter();
constructor() {}
emitMerchant(data) {
this.emittedMerchant.emit(data);
}
getEmittedValue() {
return this.emittedMerchant;
}
}
MerchantComponent (TRIGGERING EMIT FROM THIS COMPONENT)
private getMerchantDetail() {
let data = {
Id: this.merchantId,
}
this.merchantsService.getMerchants(data)
.then((res) => {
// console.log(res)
if (res.Success) {
this.merchant = res.Data[0];
this.merchantListDetailService.emitMerchant(res.Data[0]);
}
})
.catch((err) => { })
}
MerchantPaymentChannelComponent (SUBSCRIBING FROM THIS COMPONENT)
ngOnInit() {
this.merchantSubscribe = this.merchantListDetailService.getEmittedValue()
.subscribe(merchant => {
this.merchant = merchant;
this.getMerchantPaymentChannels();
})
}
ngOnDestroy() {
this.merchantSubscribe.unsubscribe();
}

How transfer data from component to another component wia Subject/Observable?

I find interesting example how transfer data from one component to another component using Subject/Observable in Service:
http://plnkr.co/edit/yMBoVkxohwhPig5COgkU?p=preview
I find it similar to broadcast event from Angular 1.X. But I notice that subscribe to data changes can only component that inishiated data change. I need somehow modify this example to get data in one component after another component changed it. Console.log dos't show any error, but data-transfer not working. Can anyone help?
Service:
#Injectable()
export class ClientsService {
private _client$: Subject<Client>;
private _clients$: Subject<Client[]>;
constructor(private http: Http) {
this._client$ = <Subject<Client>>new Subject();
this._clients$ = <Subject<Client[]>>new Subject();
}
getClients(): Promise<Client[]> {
return this.http.get('api/Client')
.toPromise()
.then(res => {
this._clients$.next(res.json());
return res.json();
})
.catch(this.handleError);
}
get client$() {
return this._client$.asObservable();
}
get clients$() {
return this._clients$.asObservable();
}
clientChangeBroadcast(objClient: Client) {
this._client$.next(objClient);
}
clientsChangeBroadcast(arrClients: Client[]) {
this._clients$.next(arrClients);
}
private handleError(error: any): Promise<any> {
return Promise.reject(error.message || error);
}
First component:
#Component({
selector: 'app',
templateUrl: './app/app.component.html'
})
export class AppComponent implements OnInit {
clients: Client[];
constructor(public clientsService: ClientsService) {
this.clients = [];
}
ngOnInit() {
}
loadClients() {
this.clientsService.getClients().then(clients => {
this.clients = clients;
this.clientsService.clientsChangeBroadcast(clients);
});
}
selectClient(objClient: Client) {
this.clientsService.getClients();
this.clientsService.clientChangeBroadcast(objClient);
}
}
Second component:
export class TestComponent implements OnInit {
client: Observable<Client>;
clients: Observable<Client[]>;
constructor(private clinetsService: ClientsService) {
}
ngOnInit() {
//this.clinetsService.getClients();
this.client = this.clinetsService.client$;
this.clients = this.clinetsService.clients$;
this.clinetsService.client$.subscribe(value => {
// try to get changes here
});
this.clinetsService.clients$.subscribe(value => {
// try to get changes here
});
}
reLoadClients() {
this.clinetsService.getClients();
}
}
I try to get data changinf in 'Second component' after data was changed by 'First component'. When I click on button for 'selectClient' method in 'First component' I expect data transfer wia service and I catch changes ob 'Second component' -> it not working. When from 'Second component' I press button for 'reLoadClients' data transfer wia service and I catch changes in all subscribe functions on 'Second component'.

Resources