Invoke a method of ng2-pdf-viewer from angular component - javascript

I am new to angular 5. I am working on ng2-pdf-viewer. I need to invoke one of its method updateSize() in that plugin from my component. Can anyone tell me how can I access it from a component.
Here is the link of the plugin
https://www.npmjs.com/package/ng2-pdf-viewer

You can use a template reference variable to access the public methods of ng2-pdf-viewer
Add a template variable named #pdfViewer in the html file like so
<pdf-viewer
#pdfViewer
[src]="reportObject.src"
[page]="reportObject.currentPage"
[render-text]="true"
>
</pdf-viewer>
Use ViewChild decorator to reference it inside your component.
import { PdfViewerComponent } from 'ng2-pdf-viewer';
import {ViewChild} from '#angular/core';
#ViewChild('pdfViewer') pdfComponent: PdfViewerComponent;
You can now access the methods of ng2-pdf-viewer using the pdfComponent variable like so
this.pdfComponent.updateSize();

You can probably achieve this by using ViewChild.
In you html template where you use pdf-viewer, write it as something like this <pdf-viewer [src]="src"[original-size]="false" #pdfViewer></pdf-viewer>.
Add #ViewChild('pdfViewer') pdfViewer into your component.
After that, you should be able to use the method like this this.pdfViewer.updateSize() and also methods inside the pdfViewer.

Related

Shared functions across multiple angular components called on click

I have an Angular website that has several components. Many of these components include displaying text that links to other components. I route to these other components with an html element like this:
<a (click)='routeToTeamSeason(team_season_id)' [routerLink]>{{team}}</a>
and then the function looks like:
routeToTeamSeason(team_season_id: string): void{
console.log("Routing to: " + team_season_id)
this.router.navigate(['/teams/season', team_season_id])
}
Where router is an instance of the #angular/router class.
Several of my components all can use this same routing logic, and right now I have the same exact function copy and pasted into each component's .ts file. How can I create a shared function that will be recognized by each component's html template?
Not sure this is the best method, but here is the solution I found:
create a separate file route-to-team-season.ts:
export function routeToTeamSeason(team_season_id: string): void{
console.log("Routing to: " + team_season_id)
this.router.navigate(['/teams/season', team_season_id])
}
Then import that function into any component and declare it locally:
myRouteToTeamSeason = routeToTeamSeason
Finally, update the template to call myRouteToTeamSeason(...)
This seems a little ugly to me, so if someone has a nicer solution, let me know!

How to use the instance of class in another file?

I am using babylonjs in my React app. Since this file get bigger and bigger I try to split it into several parts.
Scene3d.js
import * as Setup from './Scene3d/setup'
class Scene3d extends Component {
...
}
export default Scene3d
setup.js
import Scene3d from '../Scene3d'
Unfortuantely I am not able to use the instance object of Scene3d. Scene3d just returns the component in setup.js. I want to avoid to add "this" to all function to pass the object to the functions.
I appreaciate your help.
Best

Import JS class inside AngularJS Controller

I have two separat JS-files: an AngularJS(1.4x) Controller someController.js, and custom-class.js, which contains the class CustomClass.
I would like to access CustomClass and its functions from within the Controller.
Can that be achieved by using import inside the Controller and export in the corresponding file?
If not, what options do I have, instead?

Angular 4: When and why is #Inject is used in constructor?

Problem Statment
I am learning Angular 4 and I have stumble upon a code where #Inject is being used in a constructor and I am not able to figure out why...
Code and Source
I am using Angular 4 Material
Code Source: https://material.angular.io/components/dialog/overview
In the code, they are injecting MAT_DIALOG_DATA
constructor(public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
#Inject(MAT_DIALOG_DATA) public data: any
) { }
Can anyone please elaborate what does it mean and when/where should we do this?
#Inject() is a manual mechanism for letting Angular know that a
parameter must be injected.
import { Component, Inject } from '#angular/core';
import { ChatWidget } from '../components/chat-widget';
#Component({
selector: 'app-root',
template: `Encryption: {{ encryption }}`
})
export class AppComponent {
encryption = this.chatWidget.chatSocket.encryption;
constructor(#Inject(ChatWidget) private chatWidget) { }
}
In the above we've asked for chatWidget to be the singleton Angular
associates with the class symbol ChatWidget by calling
#Inject(ChatWidget). It's important to note that we're using
ChatWidget for its typings and as a reference to its singleton.
We are not using ChatWidget to instantiate anything, Angular does
that for us behind the scenes
From https://angular-2-training-book.rangle.io/handout/di/angular2/inject_and_injectable.html
If MAT_DIALOG_DATA is a non-factory/class dependency (like string for your configs), you usually use #Inject.
Also check InjectionToken: https://angular.io/guide/dependency-injection#injectiontoken
One solution to choosing a provider token for non-class dependencies is to define and use an InjectionToken
Here's a plunker: http://plnkr.co/edit/GAsVdGfeRpASiBEy66Pu?p=preview
if you remove #Inject in these cases you will receive a
Can't resolve all parameters for ComponentName: (?)
IoC container in Angular uses the type declarations in the constructor to determine the objects to be injected to the constructor parameters.
In your example, "public data: any" parameter could not be determined by its type declaration because it's defined as "any". In order to solve this problem, you have to use "#Inject(MAT_DIALOG_DATA)" decorator to inform the IoC container about the object that must be injected to "data" parameter.
Also in your example, "#Inject" decorator is used with an InjectionToken to complicate things a little more :)
An InjectionToken is actually a class which is used to name the objects to be used by IoC container to inject in to other classes. Normally you could use any classes name as a token for IoC injection (like "MatDialogRef<DialogOverviewExampleDialog>" in your example) and this works fine. But when you start writing your UnitTests you realize that you need to use Mock objects instead of real objects to be injected into your classes and when you use real class names as your tokens, you could not do that.
To solve this problem you could use Interfaces as token names and this is actually the right solution, but since JavaScript does not support interfaces you could not use Interface names as tokens, because transpiled code does not contain Interface definitions.
As a result of all this, you need to use InjectionToken. An InjectionToken allows you to inject any object into your constructor. You just need to declare it in your modules and map to the real class that you want to be injected. This way you could use different classes for your production and test codes.

How to design a global class for storing settings in Angular?

I have added a class like this.
export class Settings{
public data: string = "blopp";
}
When I try to access the data, it seems that the field I'm trying to assign that value to sees the class Settings itself but it doesn't recognize the data thingy.
How do I redesign the class to provide settings for other components?
I've read about #Output decorator but since I won't be binding to the values, it seems not the correct approach. I've made sure that the class is imported and recognized withing the component that's supposed to consume it. I've also tried the corresponding exposure but using a function in the class with settings - the same, failed result.
If you're using angular-cli and going to store in this class environment specific settings - you already have built in support for this.
Put the setting into environment.ts. For example:
export const environment = {
production: false,
someSetting: 'foo',
};
Then it can be consumed from anywhere within the app:
import { environment } from "../environments/environment"; //fix according to your project structure
#Injectable()
export class SampleService {
private foo = environment.someSetting;
}
Here you can find more info on how to add more environments and build you project with specific environment settings.
Your best bet for storing global settings is to use a service. The code for that looks like this:
import { Injectable } from '#angular/core';
#Injectable()
export class DataService {
serviceData: string;
}
I have a blog post about this here: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/
And a plunker here: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview
Also, the #Output decorator is only for communication between a child component and a parent component where the child is nested within the parent.

Categories