Cant show name of logged-in user - angular2 -meteor - node.js

I just want to show the name of the current logged in user, but I cant make it works.
I wrote this on the app.component:
import { Component } from '#angular/core';
import template from './app.component.html';
import {ROUTER_DIRECTIVES} from '#angular/router';
import {LoginButtons} from 'angular2-meteor-accounts-ui';
//import our Carousel Component
import {CSSCarouselComponent} from './imports/componenets/carousel/carousel.component';
import { InjectUser } from 'angular2-meteor-accounts-ui';
#Component({
selector: 'app',
template,
directives: [ROUTER_DIRECTIVES, LoginButtons,CSSCarouselComponent]
})
#InjectUser('user')
export class AppComponent {
user: Meteor.User;
constructor() {
console.log(this.user);
}
loginFacebook(event) {
Meteor.loginWithFacebook({}, function(err){
if (err) {
throw new Meteor.Error("Facebook login failed");
}
console.log(Meteor.user().profile.name;);
});
}
}
console.log(this.user); returns undefined.
console.log(Meteor.user().profile.name;); works and gives me the name, but I have no success to export it to the html and show that.

You have to reference Meteor in your Component, for example as let M = Meteor;. Then you can use {{M.user().profile.name}} in your html.
Also this.user is never set in your code, you just define its class. Anyway, you should always use Meteor.user() or M.user(), because it's always up-to-date.

Related

Adding a new card to the DB

I am trying to add a new card to the database.
I have a page in React that when a user fills the form and clicks "Next", a new user is created and added to the Database.
The next page is Business Information he needs to fill, but when he clicks on "Create Card" it doesn't do anything and the Database remains empty.
This is the code for my BusinessRegistrationPage.js:
import {toast} from 'react-toastify';
import {Container} from 'react-bootstrap';
import SimpleRegistrationComp from "../components/simple-registration/SimpleRegistrationComp";
import CreateCardComp from '../components/my-cards/CreateCardComp';
import {useState} from 'react';
function BusinessRegistrationPage () {
const[isStep1,setIsStep1]= useState(true);
return <Container>
{isStep1&&
<SimpleRegistrationComp clickHandler={registerUser}
text="Next" >
</SimpleRegistrationComp>
}
{
!isStep1&& <CreateCardComp clickHandler={createCard} ></CreateCardComp>
}
</Container>;
function registerUser(data) {
registerNewAccount(data,
(data)=>{
if(data._id){
toast('Account Created Successfully');
setIsStep1(false);
}
else
{
toast('Eror Acount was not created');
}
});
}
function createCard() {
alert('create card');
}
}
export default BusinessRegistrationPage;```

NestJs: Import service from another module

I'm trying to use the surveyService in the voteOptionRepository, but when I use the route, the console return this: TypeError: this.surveyService.getSurveyById is not a function
This is my SurveyModule
#Module({
imports: [
TypeOrmModule.forFeature([SurveyRepository]),
AuthModule
],
controllers: [SurveyController],
providers: [SurveyService],
exports: [SurveyService]
})
export class SurveyModule{}
This is my voteOptionModule
#Module({
imports: [
TypeOrmModule.forFeature([VoteOptionRepository]),
AuthModule,
SurveyModule
],
controllers: [VoteOptionController],
providers: [VoteOptionService]
})
export class VoteOptionModule{}
And this is how I'm trying to use the service
#EntityRepository(VoteOption)
export class VoteOptionRepository extends Repository<VoteOption>{
constructor(private surveyService: SurveyService){
super();
}
async createVoteOption(createVoteOptionDTO: CreateVoteOptionDTO, surveyId: number, user: User){
const survey = await this.surveyService.getSurveyById(surveyId, user)
const { voteOptionName, image } = createVoteOptionDTO;
const voteOption = new VoteOption();
voteOption.voteOptionName = voteOptionName;
voteOption.image = image;
voteOption.survey = survey;
try{
await voteOption.save()
this.surveyService.updateSurveyVoteOptions(voteOption, surveyId, user)
} catch(error){
throw new InternalServerErrorException();
}
delete voteOption.survey;
return voteOption;
}
}
TypeORM repository classes do not adhere to Nest's Dependency Injection System, due to being tied TypeORM. Repository classes are actually supposed to have connections and entity managers passed to them in the constructor to allow for communication with the database. If you need logic from other services, you should generally be calling those other services from inside the service call, not the repository.
I'm new to NestJS, but I believe this is what you want to do. You need to inject the reference to your table in your service.
export class VoteOptionRepository extends Repository<VoteOption>{
constructor(
private surveyService: SurveyService
#InjectRepository
surveyServiceRepo(SurveyRepository)
){
super();
}
async getSurveyById () {
const survey = await this.surveyServiceRepo.find({id: 'survey-id'})
return survey
}
}
Without seeing your SurveyService though, it may be that getSurveyById has not been defined properly, which is why your getting an error that it's not a function.

How to share UI state in single-spa using RxJs?

As per the single-spa official doc, we can share the application's UI state by using RxJs.
Observables / Subjects (RxJs) - one microfrontend emits new values to
a stream that can be consumed by any other microfrontend. It exports
the observable to all microfrontends from its in-browser module, so
that others may import it.
Link: https://single-spa.js.org/docs/recommended-setup/#ui-state
Link: https://single-spa.js.org/docs/faq/#how-can-i-share-application-state-between-applications
I was trying to create an example in React, where I am using single-spa parcel to include my micro-apps in root application. I was trying to share the UI state using RxJs.
When I googled it for single-spa RxJs, I didn't find anything. Can anyone provide me a basic example where I will be able to share UI state for below use cases:
Sharing the UI state from root app to my micro-apps.
Sharing the UI state from micro-apps to root apps.
Sharing the UI state between micro-apps.
Here is a high level overview on how to approach this:
add rxjs as a shared dependency in your import map
"rxjs": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs.min.js,
"rxjs/operators": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs-operators.min.js,
consider pinning these to a specific version!
create a utility module (create-single-spa makes this easy!) that sets up and exports the observable with data that you need
include this utility module in importmap too
import and subscribe to observable from the utility module in the apps that need it
don't forget to unsubscribe when your apps unmount.
celebrate 🎉
I have created single-spa-example-rxjs-shared-state as an example repo that shows how to use an Rxjs utility module with cross-frontend imports.
This does the trick
In root html js file add the following
Import { Subject, Subscription } from 'https://dev.jspm.io/rxjs#6/_esm2015';
import { filter, map } from 'https://dev.jspm.io/rxjs#6/_esm2015/operators';
export class EventBusService {
constructor() {this.subject$ = new Subject(); }
emit(event) {
this.subject$.next(event);
}
on(eventName, action) {
return this.subject$.pipe(
filter( (e) => e.name === eventName),
map( (e) => e["data"])).subscribe(action);
}
}
var EventBus= new EventBusService()`enter code here`;
System.import('single-spa').then(function (singleSpa) {
singleSpa.registerApplication(
'app1',
function () {
return System.import('app1');
},
function (location) {
return true;
// return location.pathname.startsWith('/app1');
},
{ EventBus: EventBus }
);
singleSpa.registerApplication(
'app2',
function () {
return System.import('app2');
},
function (location) {
return true
// return location.pathname.startsWith('/app2');
},
{ EventBus: EventBus }
)
singleSpa.start();
})
In component
import { Component,OnInit ,ChangeDetectorRef} from '#angular/core';
import { assetUrl } from 'src/single-spa/asset-url';
import { singleSpaPropsSubject, SingleSpaProps } from 'src/single-spa/single-spa-props';
import { Subscription } from 'rxjs';
#Component({
selector: 'app1-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
singleSpaProps: SingleSpaProps;
subscription: Subscription;
title = 'app1';
yoshiUrl = assetUrl("yoshi.png");
msgFromMicro="";
titleToPass="";
constructor(private ChangeDetectorRef:ChangeDetectorRef){
}
ngOnInit(): void {
this.subscription = singleSpaPropsSubject.subscribe(
props => {
this.singleSpaProps = props;
console.log(props);
this.lookForEvents();
}
);
}
lookForEvents(){
this.singleSpaProps['EventBus'].on('msgFrmMicro2',(data)=>{
this.msgFromMicro=data;
this.ChangeDetectorRef.detectChanges();
});
}
sendMsg(){
// alert(this.titleToPass);
debugger;
this.singleSpaProps['EventBus'].emit({name:'msgFrmMicro1',data:this.titleToPass});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
Take look at the following repo, handled the same scenario by passing observable ref to micro apps through customprops of single spa
https://github.com/SENTHILnew/micro_spa_intercom

Nestjs CQRS - CommandHandlerNotFoundException

I am trying to use events in my nestjs app.
However when I attempt to trigger command, I get CommandHandlerNotFoundException.
I have message-bus.module:
#Module({
imports: [CqrsModule],
providers: [
MessageBusLocalService,
StartWorkflowHandler
],
exports: [MessageBusLocalService]
})
export class MessageBusModule {
}
message-bus-local.service
#Injectable()
export class MessageBusLocalService {
constructor(private readonly commandBus: CommandBus, private eb: EventBus) {
}
startWorkflow(workflowId: string, payload: any) {
return this.commandBus.execute(
new StartWorkflowCommand(workflowId, payload)
);
}
}
and start-workflow.handler
#CommandHandler(StartWorkflowCommand)
export class StartWorkflowHandler implements ICommandHandler<StartWorkflowCommand> {
constructor() {}
async execute(command: StartWorkflowCommand) {
console.log('Workflow started', command.jobId);
return true;
}
}
I am trying to trigger command when app is bootstrapped:
const app = await NestFactory.create(ApplicationModule);
const service = app.get(MessageBusLocalService);
try {
const c = await service.startWorkflow('abcde', {just: "test"});
console.log('And returned', c);
} catch (e) {
console.error(e)
}
and... I get the CommandHandlerNotFoundException there although I believe it is declared... What did I do wrong?
Thanks in advance.
Since you want to use the handler in another module (e.g. appModule ) you need to add the #Injectable() decorator to the StartWorkflowHandler class.
And call app.init() in the main.ts. Before starting the application.
Your MessageBusModule does not re-export handlers, thus they are not "visible" on app.module level (at least this is what I understand on my own)
I got similar scenario like that:
const commands = [NewOrder, ChargeForOrder]
const events = [ChargeOrder, OrderProcessed]
const sagas = [AdjustWalletFunds]
#Module({
imports: [
CqrsModule,
WalletsModule,
TypeOrmModule.forFeature([...]),
],
providers: [...commands, ...events, ...sagas],
exports: [CqrsModule, ...commands, ...events, ...sagas],
})
export class RxModule {}
so, assuming you import your MessageBusModule in the main app.module, try the following:
#Module({
imports: [CqrsModule],
providers: [
MessageBusLocalService,
StartWorkflowHandler
],
exports: [MessageBusLocalService, StartWorkflowHandler]
})
export class MessageBusModule {
}
As it turns out, the method I used in the question does not work.
However it does work as expected if I inject the MessageBusLocalService in controller.
It seems odd to answer my own question but it might help someone eventually.
Ensure you imported have CqrsModule imported. Also import the MessageBusModule into any other module where it is called from.

Getting an error that a property doesn't exist when it is showing up on the page accurately

I'm calling a twitter API from angular and then node, but I'm getting an error that a property doesn't exist on type 'Object'. But it is showing up on the page properly.
I've tried renaming the property and looked through the tweet service that I have set up, but I can't seem to figure out what's going wrong.
import { Component, OnInit } from '#angular/core';
import { TweetService } from '../../services/tweet.service';
#Component({
selector: 'app-twitter-page',
templateUrl: './twitter-page.component.html',
styleUrls: ['./twitter-page.component.scss']
})
export class TwitterPageComponent implements OnInit {
tweetsArray;
constructor(
private twitter: TweetService
) { }
ngOnInit() {
this.twitter.getTweets().subscribe(tweet => {
this.tweetsArray = tweet.tweets[0];
console.log(this.tweetsArray);
});
}
}
Error:
ERROR in src/app/main-body/twitter-page/twitter-page.component.ts(20,32): error TS2339: Property 'tweets' does not exist on type 'Object'.
Here tweet is of the type Object which do not have attributes on it.
You should define an interface ITweet and cast tweet to this interface. This gives a shape to the tweet object and defines the set of attributes available on it.
tweet.ts -
export interface ITweet {
...
};
twitter-page.component.ts - (note - .subscribe((tweet:ITweet) => {}))
import { ITweet } from './tweet.ts';
.
.
.
export class TwitterPageComponent implements OnInit {
.
.
.
ngOnInit() {
this.twitter.getTweets().subscribe((tweet:ITweet) => {
this.tweetsArray = tweet.tweets[0];
console.log(this.tweetsArray);
});
}
}
Or alternatively you can just cast tweet to any (.subscribe((tweet:any) => {})). But this is not recommended since you will lose the benefit of type checking.

Resources