I am trying to use the Braintree SDK (braintree-web) in my Angular2 app. I'd really appreciate any pointers on how to get this working. I think it is because I am not importing the braintree-web module, but I can't figure out how to to that either. I can find any exports in the whole module.
Here is where I am:
I've imported the braintree-web library and a typings file I found.
ng install --save braintree-web
npm install #types/braintree-web#3.0.1
I tried to hack the JS example Braintree provides into a Angular2 TS Component, but I keep getting an error:
EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in
./UpaccountComponent class UpaccountComponent - inline template:5:7
ORIGINAL EXCEPTION: TypeError: this.braintree.setup is not a function
Here is the .ts file.
import { Component, OnInit } from '#angular/core';
declare var braintree:any;
#Component({
selector: 'up-btcheckoutform',
templateUrl: './btcheckoutform.component.html',
styleUrls: ['./btcheckoutform.component.css']
})
export class BtCheckoutFormComponent implements OnInit {
braintree = require('BrainTreeWeb');
// braintree = require('braintree-web');
integration: any
constructor() { }
ngOnInit() {
var c = this;
var clientToken = "CLIENT_TOKEN_GOES_HERE";
braintree.setup(clientToken, "dropin", {
container: "payment-form",
onReady: function(int) {
c.integration = int
}
});
}
ngOnDestroy() {
this.integration.teardown();
}
}
I'm not sure about the usage of braintree-web specifically, but if you're using webpack, remove the lines declare var braintree:any; and braintree = require('BrainTreeWeb');
You'll also need to add the braintree-web/index.js file to the bundle, unless they've got a UMD module.
From a quick glance at braintree-web, it looks like braintree.setup(..) isn't a function. Something like this might be equivalent:
braintree.client.create({
authorization: "long-token-string"},
(err, client) => {
// Do stuff here
client.request({..});
});
With the package installs, you'll need to have added --save-dev to the types install.
I have integrated the brain-tree the same way as you have done and it works.
I've just installed one more command
first install
npm install #types/braintree-web#3.0.1er
then install
npm install --save braintree-web#2.30.0
and use
braintree = require('braintree-web');
Again if it asks for braintree is not defined then remove declare var braintree:any;
and replace bellow code
braintree.setup(clientToken, "dropin", {
container: "payment-form",
onReady: function(int) {
c.integration = int
}
});
with
this.braintree.setup(clientToken, "dropin", {
this.container: "payment-form",
onReady: function(int) {
c.integration = int
}
});
Edit:
just declare the var after import declare var braintree:any; if your working with angular 4 then declare declare var require: any;
You can also import it via:
import * as braintree from 'braintree-web';
Refer this:
Refrring 3rd party JS libraries in angular 2
It's a universal solution. You don't even need to use any npm packages. Just simply refer BrainTree JS libarary in index.html and follow the steps documented in above link. It's applicable for any JS library.
Related
I installed a npm package which contains a javascript file, what I want to use. The js file name is all.js and contains this code:
import { initExtended } from './extended'
import Header from './components/header/header'
function initAll(options) {
// Set the options to an empty object by default if no options are passed.
options = typeof options !== 'undefined' ? options : {}
// Allow the user to initialise GOV.UK Frontend in only certain sections of the page
// Defaults to the entire document if nothing is set.
var scope = typeof options.scope !== 'undefined' ? options.scope : document
// Find first header module to enhance.
var $toggleButton = scope.querySelector('[data-module="govuk-header"]')
new Header($toggleButton).init()
initExtended(options)
}
export {
initAll,
Header
}
File all.js is located in node_modules.
When I tried to import it directly from index.html like:
<script type="module" src="node_modules/#id-sk/frontend/govuk/all.js"></script>
It is not working. Console error, file not found.
I also tried import it via angular.json:
"scripts": [
"./node_modules/#id-sk/frontend/govuk/all.js"
]
Also not working with error "Uncaught SyntaxError: Cannot use import statement outside a module (at scripts.js:15241:1)". The error refers to line:
import { initExtended } from './extended'
I also tried to import it in polyfills but I don't know how to call it.
As you are speaking about angular.json, I assume that you are working in an Angular application bootstrapped using the Angular CLI with default settings.
To be able to use this package #id-sk/frontend in your typescript files, you have to import it directly into your typescript file.
1. Import #id-sk/frontend in your TS files
// Import everything into a local variable
import * as govuk from '#id-sk/frontend';
// Import specific object
import { HeaderExtended } from '#id-sk/frontend';
2. Run ng serve
⚠ Spoil: It will lead to typings errors
3. Let's add or create typings
As #id-sk/frontend is not written in typescript, the compile doesn't know about the typings of this library.
Following this statement, you have two choices:
Find or contribute to DefinitelyTyped in order to create the typings of your package #id-sk/frontend
Create a local file typings.d.ts in your ./src folder to declare an empty module
declare module "#id-sk/frontend"
4. Kill & run ng serve again
Enjoy it!
Go further
You can add typings to your module in order to give you autocompletion on the provided objects of #id-sk/frontend.
``ts
declare module "#id-sk/frontend" {
export interface Options {
scope?: Document
}
export function initAll(options: Options): void;
}
I'm trying to build a web component that will host the ace editor. The trouble is that I don't find enough information on how to import the module and set the types. The code bellow was working just fine using simple <script> tags and global vars.
So far this is what I have:
npm install ace-code-editor --save
npm install #types/ace --save-dev
code-editor.cmp.ts
// Error: [ts] File '.../node_modules/#types/ace/index.d.ts' is not a module.
import * as ace from 'ace';
export class CodeEditorCmp extends HTMLElement {
// DOM
private editor: AceAjax; // How do I import the type. What type to use?
constructor() {
super();
}
connectedCallback() {
this.initCodeEditor();
}
initCodeEditor(){
this.editor = ace.edit("editor-vsc");
// How do I import the editor themes?
this.editor.setTheme("ace/theme/xcode");
// How do I import the editor modes?
var JavaScriptMode = ace.require("ace/mode/html").Mode;
this.editor.session.setMode(new JavaScriptMode());
this.editor.getSession().setTabSize(4);
this.editor.getSession().setUseSoftTabs(true);
this.editor.getSession().setUseWrapMode(true);
this.editor.setAutoScrollEditorIntoView(true);
// Update document
this.editor.getSession().on('change', this.onEditorChange);
}
onEditorChange(){
}
}
require('./code-editor.cmp.scss');
window.customElements.define('editor-vsc', CodeEditorCmp);
For those who don't want to use the brace module, I saw that my issue was that I was importing the wrong version of ace. Once installed, make sure to import from src-noconflict. The noconflict version uses ace.require which seems to play a lot more nicely than the other iterations that use require.
I would suggest that you do the following:
npm install ace-builds --save
npm install #types/ace --save-dev
Afterwards in your file just import the noconflict like below:
import * as ace from 'ace-builds/src-noconflict/ace';
This will result in a variable ace being defined. You will then be able to reference methods and properties of ace as normal, such as ace.edit()
You can get more information about the different versions of ace check out the git page.
After a lot of digging I managed to find brace module. It's a browserify wrapper for ace. Fortunately it works straight away with webpack. No need to use separate types, they come prepackaged.
import * as ace from 'brace';
import 'brace/mode/javascript';
import 'brace/theme/monokai';
export class CodeEditorCmp extends HTMLElement {
private editor: ace.Editor;
initCodeEditor(){
this.editor = ace.edit('javascript-editor');
this.editor.getSession().setMode('ace/mode/javascript');
this.editor.setTheme('ace/theme/monokai');
//...
}
//...
}
I have this module.ts file:
import { IHttpService, IPromise } from 'angular';
export class ProductService {
static $inject = ["$http"];
constructor(private $http: IHttpService) { }
loaded: boolean = false;
promise: IPromise<{ data: any }>;
getProducts(): IPromise<{ data: any }> {
if (!this.loaded) {
this.loaded = true;
this.promise = this.$http.get('/products.json');
}
return this.promise;
}
}
var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);
and this gets transpiled/compiled to module.js:
"use strict";
var ProductService = (function () {
function ProductService($http) {
this.$http = $http;
this.loaded = false;
}
ProductService.prototype.getProducts = function () {
if (!this.loaded) {
this.loaded = true;
this.promise = this.$http.get('/products.json');
}
return this.promise;
};
ProductService.$inject = ["$http"];
return ProductService;
}());
exports.ProductService = ProductService;
var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);
The problematic line is: exports.ProductService = ProductService; If I remove this manually - the app works perfectly. But if I leave this like that, in the browsers console I get an error "exports is not defined".
What can be done about this? I can't just remove "export" from the .ts file as this class is used in other files (I import it there). I tried different compiler options, but it just gives me different errors (like "define is not defined" etc) and I'm not sure how to handle this. maybe theres a way that the tsc would just not produce this line?
Whenever you use the import and export keywords in typescript, you are converting the file to act as a module.
Modules are designed to work along with module systems like commonjs,amd, es6, systemjs etc...
If your are trying to load a raw script in a browser without using a module-loader or bundler such as systemjs, webpack, browserify, jspm, etc... then you cannot use external modules (so you can't use import/exports).
You can still use typings from definitely typed, but you have to load them through ///<reference /> tags.
If using typescript 2.0 typings like angular are also available and imported by default when you run
npm install #types/angular
Usually these typings will expose global namespace declaration that you will now be able to use throughout your application.
For example in your case angular exposes an ng namespace and you would use it like:
promise: ng.IPromise<{ data: any }>;
You can also easily alias it:
import IPromise = ng.IPromise
Note that this import behaves differently than module imports (it just aliases).
If you are going to do anything other than a trivial application, I would strongly recommend you use a module loader such as webpack to compile and bundle the application for the browser. There are many limitations to just using plain scripts.
I'm having trouble importing Showdown as a vendor. When I compile, I get showdown is not defined in the browser console. Since it is a vendor package, I don't think I can import it inside of app.module.ts. Do I need to declare a custom typing for it? The package is all in js. I am running on Angular2 RC5. Thanks!
home.service.ts
import 'showdown/dist/showdown';
declare var showdown: any;
private extractData(res: Response) {
let body = res.json();
var converter = new showdown.Converter(),
originalBody = window.atob(body.content),
body.title = converter.makeHtml(title);
}
vendor.browser.ts
import 'showdown/dist/showdown';
I'm not familiar with the Showdown, but if you want to import it in the code you need to have type definition files. If you use TypeScript 2.0, you can simply install it from npmjs.org. I just checked - they have the type definitions for Showdown in the #types organization: https://www.npmjs.com/search?q=%40types%2Fshowdown
Just run npm i #types/showdown --save-dev.
If you use older TypeScript, install the declarations with Typings.
Don't forget to add a script tag for Showdown in your index.html.
In this sample app I use JQuery implicitely, but don't need to import it though:
https://github.com/Farata/angular2typescript/tree/master/chapter2/auction
Solution was to employ typings mentioned by Yakov Fain
import {Converter} from "showdown/dist/showdown";
const converter = new Converter();
var body.title = converter.makeHtml(title);
I'm trying to implement auth0 into my Angular 2 project, and I don't want to use the lock widget but instead customize my own login form and buttons for social login. So I want to use the auth0-library on it's own. And I want it to be bundled, so not import it in index.html.
I've used the CLI to scaffold my project (1.0.0-beta.11-webpack.2) and installed auth0-js with NPM. I can find the 'auth0-js'-folder in my node_modules, now I just have to connect it to my app somehow.
// login.component
import { Component } from '#angular/core';
import * as Auth0 from "auth0-js";
#Component({
selector: 'app-login',
templateUrl: 'login.component.html',
styleUrls: ['login.component.css']
})
export class LoginComponent implements OnInit {
auth0: any;
constructor() {
this.auth0 = new Auth0({
domain: 'myDomain',
clientID: 'myClientId',
callbackURL: '{http://localhost:4000/}', // in dev-mode
callbackOnLocationHash: true
});
}
loginWithGoogle(connection) {
this.auth0.login({
connection: 'google-oauth2'
});
}
}
But I get this console message from Webpack:
ERROR in [default] ......... /node_modules/#types/auth0-js/index.d.ts' is not a module.
It seems the app is working, although the typings doesn't work. I've installed with npm i #types/auth0-js --save and it installs the typings to my node modules as expected.
Seems it's something wrong with the typings, but what? And is it something I can fix myself or do I have to wait until someone updates the typings to be modular?
Thanks!!
I have not used Auth0. But I think this should work.
main.ts
import 'auth0-js/standalone';
// Add this to test it.
var auth0 = new Auth0({
domain: 'mine.auth0.com',
clientID: 'dsa7d77dsa7d7',
callbackURL: 'http://my-app.com/callback',
responseType: 'token'
});
Quick typings work around src/typings.d.ts
declare var Auth0: any;
A better way to do typings:
Install the auth0 typings https://www.npmjs.com/package/#types/auth0
Update your tsconfig "types": ["auth0"]