angular js code not working with external plugin - javascript

I am trying to use intercom in my app to monitor user activity.
its working fine when I put inside script tag in index.html
but when I try to use in .ts file I am getting below error.
app/components/rocket/rocket-search.ts(63,10): error TS2339: Property 'intercomSettings' does not exist on type 'Window'.
can you tell me how to fix it.
providing my code below
not working code
import { Component, ElementRef, Input, Output, EventEmitter, Inject, OnInit, ViewChild } from '#angular/core';
import { KendoGridComponent } from '../grid/grid.component'
import { Router } from '#angular/router';
import { sportsService } from '../../services/sports.service';
#Component({
selector: 'rocketSearch',
templateUrl: "./app/components/rocket/rocket-search.html",
})
export class rocketSearch {
/* Localization variables */
#Output() rocketSearchEmitter: EventEmitter<any> = new EventEmitter<any>();
private dataSourceVal;
private MainGrid;
private grid;
private titles;
public rocketRef;
constructor( public elementRef: ElementRef, public router: Router, public sportsService: sportsService) {
}
private kendocommand = {
edit: { createAt: "bottom" },
autoBind: false,
excelFileName: {
fileName: "",
allPages: true
}
}
ngOnInit() {
let that = this;
let attributes = this.sportsService.getSeesionStorageValue();
// if (attributes) {
// this.userId = attributes.user_attributes.SSO[0];
// }
//app/components/rocket/rocket-search.ts(63,10): error TS2339: Property 'intercomSettings' does not exist on type 'Window'.
window.intercomSettings = {
app_id: 'irgooiqb',
name: "Jane Doe", // Full name
email: "customer#example.com", // Email address
created_at: 1312182000 // Signup date as a Unix timestamp
};
//console.log(.log(this.userId);
}
}
working code inside index.html
<script>
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/APP_ID';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()
</script>
<script>
let players=this.sportsService.marksSession();
console.log("players--->" + players);
if(players) {
this.userId = players.user_players.SSO[0];
}
Intercom('trackEvent', 'share-link');
window.intercomSettings = {
app_id: 'APP_ID',
name: "Jane Doe", // Full name
email: "customer#example.com", // Email address
created_at: 1312182000 // Signup date as a Unix timestamp
};
</script>

well it wouldn't work, the code in your html actually fetches the intercom js library from the URL https://widget.intercom.io/widget/APP_ID which the code in your typescript do not.
A better approach is to install the intercom npm package that you can then import in your code, however I don't write typescript so I'm unsure if there would be any issue using the package in a typescript fashion.

Related

Uploading Blob images in firebase storage using putString in AngularFire

I created an Electron - Angular project where I can do a screenshot remotely, this generate this blob (I name it as ssUrl / this.ssUrl in the code below)
I don't want it to be saved locally but instead to be uploaded directly to firebase storage, I've been following some documentations and altering it a bit to fit my codebase, however this generates an error.
Here is my code:
import {
AngularFirestore,
AngularFirestoreCollection,
} from '#angular/fire/compat/firestore';
import { Observable, concatWith } from 'rxjs';
import {
AngularFireStorage,
AngularFireUploadTask,
} from '#angular/fire/compat/storage';
#Component({
selector: 'app-autoupload',
templateUrl: './autoupload.component.html',
styleUrls: ['./autoupload.component.scss'],
})
export class LoginComponent implements OnInit {
constructor(
private afs: AngularFirestore,
private afsU: AngularFireStorage
) {}
checkSS() {
if (this.ssRequest == true) {
this.getScreenshot(); // executes IpcServices to get screenshot using electron
console.log('ready to upload', this.ssUrl); // generated URL from electron
// Uploading to Firebase storage
this.imagePathName = 'gallery' + Math.random();
this.imageRef = this.afsU.ref(this.imagePathName);
this.imageRef.putString(this.ssUrl, 'base64', {contentType: 'image/png'});
this.imageSub = this.imageBaseRef
.snapshotChanges()
.pipe(concatWith(this.imageRef.getDownloadURL()))
.subscribe((url: Observable<string>) => {
this.downloadUrl = url;
this.galleryUrl = this.downloadUrl;
this.galleryLogDate = new Date();
this.afs.collection('gallery').add({
ssUrl: this.galleryUrl,
profileId: this.loggedProfileId,
userName: this.loggedUsername,
});
});
}
}
}
generates two error
I know there's something wrong on how I upload it using putString or maybe I'm using the wrong method on storage ref. I tried other approaches but also ending up getting more errors
this.imageBaseRef = this.afsU.upload(this.imagePathName, this.ssUrl);
Hopefully you could correct what me or guide me on how to fix.

Inject store into errorhandler class Angular

I am trying to implement sentry error handling into my application, now I have it set up and working as expected.. but now I want to be able to pass user information on the Sentry object for better error logging.
So I have the following setup
export class SentryErrorHandler implements ErrorHandler {
userInfo: UserInfo;
constructor(
private _store: Store<AppState>
) {
this.getUserInfo();
}
getUserInfo() {
this._store.select('userInfo')
.subscribe(result => {
this.userInfo = result;
});
}
handleError(err: any): void {
Sentry.configureScope((scope) => {
scope.setUser({
email: this.userInfo?.emailAddress,
id: this.userInfo?.id?,
});
});
const eventId = Sentry.captureException(err.originalError || err);
Sentry.showReportDialog({ eventId });
}
}
and I am providing the error handler like so in my root module
// ...
{ provide: ErrorHandler, useClass: SentryErrorHandler }
// ...
but what happens is, when I start my application I get the following error
Obviously im doing something wrong here, any help would be appreciated!
This error is happening because without the #Injectable decorator Angular cannot wire up dependencies for the class (even using it in providers).
So all you have to do is add the #Injectable() decorator in your error class.
See a demo here:
https://stackblitz.com/edit/angular-ctutia

Cannot load pdf from local file system (IONIC 4 - Android)

I got a problem where I cannot load a pdf inside a view of my app.
In my demo app for this I got two views, one "home" and one "result". In the home view I got a button which opens an android document picker with function pickDocument(). After a document has been picked the file name and file path get passed to the "result" view.
In my result view I convert the given path of the document picker to a native path in setPath(), but this path gives me a 404 on my device. I can't seem to load the file I want to display there.
The file has the local path (before converting it using setPath():
content://com.android.providers.downloads.documents/document/22
I get the following error:
Dummy-PDF.pdf:1 GET http://localhost/_app_file_/storage/emulated/0/Download/Dummy-PDF.pdf 404 (OK)
Is there anything I am missing? Or is there a better way to do, what I am trying to do? Could someone please help me to fix this issue.
I included the important code parts below. Thanks a lot.
Code of home.page.ts
...
export class HomePage {
constructor(private chooser: Chooser, private router: Router) { }
pickDocument() {
this.chooser.getFile("application/pdf")
.then(file => {
this.addFile(file.name, file.uri);
}, error => {
console.error(error);
});
}
addFile(fileName: string, fileUri: string) {
let navigationExtras: NavigationExtras = {
queryParams: {
"fileName": fileName,
"fileUri": fileUri
}
};
this.router.navigate(["result"], navigationExtras);
}
}
Code of result.page.ts
...
export class ResultPage implements OnInit {
public fileName: string;
public fileUri: string;
public path: string;
private win: any = window;
constructor(private route: ActivatedRoute, private filePath: FilePath) {
this.route.queryParams.subscribe(params => {
this.fileName = params["fileName"];
this.fileUri = params["fileUri"];
this.setPath();
});
}
ngOnInit() {
}
setPath() {
this.filePath.resolveNativePath(this.fileUri).then(path => {
this.path = this.win.Ionic.WebView.convertFileSrc(path);
});
}
}
Code of result.page.html
<ion-content>
<ion-list>
<ion-item>
<ion-img [src]="path"></ion-img>
</ion-item>
<ion-item>FileName: {{fileName}}</ion-item>
<ion-item>FileUri:{{fileUri}}</ion-item>
<ion-item>FilePath:{{path}}</ion-item>
</ion-list>
</ion-content>

Angular router.redirect doesn't populate variables

I am using Stripe checkout with my Angular 5 project and seem to be stuck on a router redirect / template lifecycle issue.
On user signup, I open the stripe checkout modal. When that modal get's a payment source token, I do some more API work and then do a router.redirect.
stripe.open({
email: 'foo#foo.com',
name: 'Subscription',
description: 'Basic Plan',
amount: 499,
token: (source) => {
this.http.post('/user/subscribe', { source: source.id }).subscribe(_ => {
this.router.navigate(['stylist/profile']);
});
}
});
The app redirects properly, but the variables do not display whatsoever. Below is an example of my page. Ideally, the redirect would trigger the ngOnInit and the test variable would be true. In my scenario, the test is displayed in the html template as blank.
Profile Route
{ path: 'stylist/profile', component: ProfilePageComponent, canActivate: [AuthGuard] },
Auth Guard
#Injectable()
export class AuthGuardService implements CanActivate {
constructor(
public auth: AuthService,
public router: Router,
public route: ActivatedRoute
) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
this.router.navigate(['']);
return false;
}
return true;
}
}
Profile Page Component
export class ProfilePageComponent implements OnInit {
test: boolean = false;
ngOnInit() {
this.test = true;
}
}
Profile Page HTML
<div>Test variable: {{test}}</div>
This code has been simplified, but I wanted to make sure I wasn't missing any strange lifecycle events due to redirecting in a callback of a callback?
I've tried subscribing to various Router and ActivatedRoute events without any luck. I've also seen solutions involving ngZone, but those didn't seem to fit the bill either.
01/07/19 UPDATE
I was able to recreate this via stackblitz per the suggestion in the comments.
https://stackblitz.com/edit/angular-un9tfk
Upon initial load of the homepage, you can click the "Open Stripe" button and fill out some dummy data. The callback then redirects to /test with a warning message in the console.
Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?
I believe this points me to doing ngZone.run()... somewhere in my signup.component.ts, but not sure where just yet.
As stated in the edit above, it turns out using Router.navigate in a function callback is technically outside of an Angular zone.
Wrapping my Router.navigate in NgZone.run(() => {}) did the trick.
Implemented solution:
import { Component, Input, NgZone } from '#angular/core';
constructor(private zone: NgZone) { }
signup() {
stripe.open({
email: 'foo#foo.com',
name: 'Subscription',
description: 'Basic Plan',
amount: 499,
token: (source) => {
this.http.post('/user/subscribe', { source: source.id }).subscribe(_ => {
this.zone.run(() => {
this.router.navigate(['stylist/profile']);
});
});
}
});
}

ionic2/angular2 - Access an object in an external file in typescript

I am building a mobile app using ionic2.
For payments online i use a simple online payment service called Paystack.
it works by including a js file in your webpage and then calling a function
<script>
function payWithPaystack(){
var handler = PaystackPop.setup({
key: 'UNIQUE_KEY_HERE',
email: 'customer#email.com',
amount: 10000,
ref: "UNIQUE TRANSACTION REFERENCE HERE",
metadata: {
custom_fields: [
{
display_name: "Mobile Number",
variable_name: "mobile_number",
value: "+2348012345678"
}
]
},
callback: function(response){
alert('success. transaction ref is ' + response.reference);
},
onClose: function(){
alert('window closed');
}
});
handler.openIframe();
}
</script>
I am trying to port this to my ionic app. The problem is that it doesn't recognise PaystackPop even though i included the js file in the index.html.
How can i resolve this? I'm guessing i have to somehow import PaystackPop the way i import other classes, but i have no idea how to go about this. Any advice?
I figured it out.
All i had to do was declare PaystackPop at the top of the file.
import { Component } from '#angular/core';
import { NavController, ViewController, ToastController } from 'ionic-angular';
declare var PaystackPop: any;

Categories