angular material design with typescript - javascript

I am brand new to typescript, typings. Vaguely understand type definition and trying to setup angular 1.5 project with typescript and angular material design.
I have angular material type definition in typings>globals>angular-material.
I don't know what module I can import and where to check. If i put like the following example, i get an exception: Module 'material' is not available!
import * as angular from 'angular';
import * as material from 'angular-material';
angular.module('app.services', []);
angular.module('app', ['app.services', 'material']);
The top portion of index.d.ts in typings>globals>angular-material is
declare module 'angular-material' {
var _: string;
export = _;
}
declare namespace angular.material { ...}
Thanks in advance.

It should be like this,
angular.module('app.services', []);
angular.module('app', ['app.services', 'ngMaterial']);

You should not import from 'angular-material'
just add a reference to typings :
/// <reference path="../typings/angular-material/angular-material.d.ts" />
(be sure to install typings for angular-materials first)
then use :
angular.module('app.services', []);
angular.module('app', ['app.services', 'ngMaterial']);

You should remove the single quotes when defining material provider for example
import * angular from 'angular';
import * as material from 'angular-material';
angular.module('app.services', []);
angular.module('app', ['app.services', material]);
This will solve your issue.
Also for importing material style sheet you can use following code.
import 'angular-material/angular-material.css';
For libraries that don't have type definitions you can use the following code.
import * as angular from 'angular';
require('../../../node_modules/angular-messages');
angular.module('app.services', []);
angular.module('app', ['app.services', 'ngMessages']);
Note : Here you should use string for defining provider

Small, I hope useful, addition (the experience I faced recently). If you need to use angular-material in TS unit tests, you will need to import it into spec file too (whereas in main code you only need to import it once and set as dependency in main module). Then it's sufficient to import 'angular-material'; at the top, and add variable for necessary service with corresponding typings, e.g. let dialog:ng.material.IDialogService;

Related

How jest in Angularjs handle all my module dependencies

Updated: I did not use any module loader, because this is old project, emm, so I just import all dependencies in my index.html via script tag
My AngularJS has a structure like this:
app.js
angular.module('app', ['LocalStorageModule', 'ngCookies', ...])
testController
angular.module('app').controller('testController', function(){})
now I want to test testController, so my jest UT code:
testController.spec.js
require('./testController.controller')
describe('TestController', () => {
beforeEach(angular.mock.module('app'));
})
but now I got an error:
Module 'app' is not available
that means I must import app.js, but if I import app.js, I also got
Failed to instantiate module LocalStorageModule due to: Module 'LocalStorageModule' is not available!
So I have to import all my dependencies(twenty an more installed by bower) in my every test file? I think it isn't a good way. How to handle this solution? import all my components installed by bower?
The problem seems to be the angular.js dependency injection. Because you have some dependencies declared in your app module. You need to mock your app module and then you need to inject the dependencies.
describe('TestController', () => {
beforeEach(
angular.mock.module('app')
);
let _localStorageModule;
let _ngCookies;
beforeEach(
inject((LocalStorageModule, ngCookies) => {
_localStorageModule = LocalStorageModule;
_ngCookies = ngCookies;
})
);
})

How do I declare a dependency on an ng-metadata module?

I have a project that is using ng-metadata (https://github.com/ngParty/ng-metadata) to build a handful of Angular 1.5 modules. I have a test module/component that looks like this:
import { NgModule, Component, Inject, Input, Output, EventEmitter } from 'ng-metadata/core'
import { platformBrowserDynamic } from 'ng-metadata/platform-browser-dynamic'
#Component({
selector: 'test',
template: require('./test.template.html')
})
class TestComponent {
#Input() type: string;
constructor() {
console.log(`test: ${this.type}`)
}
}
#NgModule({
declarations: [TestComponent]
})
class HeroModule {}
platformBrowserDynamic().bootstrapModule(HeroModule)
Everything seems happy when compiled and I'm now attempting to use the module in another project (that is not using ng-metadata but has a compatible version of Angular).
I'm simply including the shims as directed by the ng-metadata docs and the JavaScript file that contains the module described above (built by webpack). I have a new module in this project that wants to list the HeroModule as a dependency. I've tried a few things:
// attempt 1:
angular.module('my-consuming-module', ['ui.router', 'hero'])
// attempt 2:
angular.module('my-consuming-module', ['ui.router', 'heroModule'])
// attempt 3:
angular.module('my-consuming-module', ['ui.router', 'hero-module'])
All always end up with the same Error: $injector:nomod Module Unavailable error from Angular.
If I'm using ng-metadata to build my modules, what are the names I use to list them as dependencies in another project?
Finally figured this out! It's amazing what happens when you carefully read documentation...
Found in the Manual Angular 1 Bootstrap section of ng-metadata's docs:
You can still leverage ng2 way of components registration without ng-metadata bootstrap, but you have to manually create your Angular 1 module from an ng-metadata #NgModule using the bundle helper function.
I ended up being able to do the following:
// REMOVED platformBrowserDynamic().bootstrapModule(HeroModule)
const Ng1AdminModule = bundle(HeroModule).name;
export const AppModule = angular.module('hero', [Ng1AdminModule]);
And then my hero module becomes accessible to the my-consuming-module just as I expected. The bundle helper function was the key to figuring this out.
You need to import those module from their respective locations and inject it inside your angular module
//ensure `angular`, `angular-ui-router` should be there in `map` of systemjs.config.js
import * as angular from 'angular';
import * as uiRouter from 'angular-ui-router';
import { heroModule} from './hero.module';
angular.module('app',[ uiRouter, heroModule]);
Check references here

Best way to integrate angular-google-maps to an AngularJS and ES6 project through import statement

I am working on front-end of a project and using Angular v-1.5 and ES6 in this project. I am trying to integrate gMaps API into the project.
As there's no official documentation available from google for ES6 as of now, I am using angular-google-maps (link) by angular-ui(link) to do the same.
However, the problem is I couldn't find any examples or solid material to do the same.
I tried to do it through the obvious way, we do it in ES6, i.e. npm install followed by importing it into our app. But it doesn't work out. Turns out that I can't import lodash.
See the issue with lodash:
a) https://github.com/lodash/lodash/issues/1457
b) https://github.com/lodash/lodash/issues/1704
I tried these solutions mentioned in comments by one of the contributor of lodash:
a) https://github.com/lodash/lodash/issues/1704#issuecomment-164379884
b) https://github.com/lodash/lodash/issues/1704#issuecomment-164524426
but they are not working.
I still can't find anything on internet that solves this issue. I am getting the error:
Uncaught ReferenceError: _ is not defined
which is obviously due to missing lodash constant ( _ )
If nothing works out I, unfortunately, have to roll back to ES5 which would again consume a lot of time as I will have to change the structure of the project and change the entire syntax to ES5.
I am facing this exact same problem.
See here:
My app.js file:
import angular from 'angular';
// Import our app config files
import constants from './config/app.constants';
import appConfig from './config/app.config';
import appRun from './config/app.run';
import 'angular-ui-router';
import 'angular-ui-bootstrap';
import 'angular-google-maps';
import fp from 'lodash/fp';
const _ = fp();
// Import our templates file (generated by Gulp)
import './config/app.templates';
// Import our app functionaity
import './layout';
import './components';
import './home';
import './profile';
import './services';
import './auth';
import './settings';
import './dashboard';
import './maps';
// Create and bootstrap application
const requires = [
'ui.router',
'ui.bootstrap',
'uiGmapgoogle-maps',
'_',
'templates',
'app.layout',
'app.components',
'app.home',
'app.profile',
'app.article',
'app.services',
'app.auth',
'app.settings',
'app.dashboard',
'app.map'
];
// Mount on window for testing
window.app = angular.module('app', requires);
angular.module('app').constant('AppConstants', constants);
angular.module('app').config(appConfig);
angular.module('app').run(appRun);
angular.bootstrap(document, ['app'], {
strictDi: true
});
You need to include/load(via webpack) lodash: quickest way is to include this in your html:
<script src='https://cdn.jsdelivr.net/lodash/4.15.0/lodash.min.js'> </script>
I'm also having some issues getting it to work correctly with ES6, there is a issue posted on github: https://github.com/angular-ui/angular-google-maps/issues/1929

Angular services with browserfy

I've using the angular fullstack generator for a long time and I recently updated it and noticed it no longer uses bower and that it uses require to get the modules in the client. My issue is that I can't understand how this works at all when I try to declare a service.
if I run, for example, yo angular-fullstack:service example it creates a example.service.js in the client/app/example path with the following code:
'use strict';
const angular = require('angular');
/*#ngInject*/
export function exampleService() {
// AngularJS will instantiate a singleton by calling "new" on this function
}
export default angular.module('sisaApp.example', [])
.service('example', exampleService)
.name;
Let's say that I want to use $http here. Do I pass it as a parameter to the function?
Apart from that, how do I go about injecting this service into a controller?
If I run yo angular-fullstack:route myroute and it generates th following controller file:
'use strict';
const angular = require('angular');
const uiRouter = require('angular-ui-router');
import routes from './myroute.routes';
export class MyrouteComponent {
/*#ngInject*/
constructor() {
this.message = 'Hello';
}
}
export default angular.module('sisaApp.myroute', [uiRouter])
.config(routes)
.component('myroute', {
template: require('./myroute.html'),
controller: MyrouteComponent,
controllerAs: 'myrouteCtrl'
})
.name;
Doing it the old was by passing it as a parameter into the constructor doesn't seem to be working for me.
Any help would be appreciated!
Thanks in advance!

How to convert angularJS version 1.X controller into angular 2.X using EM6 ngupgrade

angular.module('app', []).controller('MessagesCtrl', function() {
$scope.self.list = [
{text: 'Hello, World!'},
{text: 'This is a message'},
{text: 'And this is another message'}
];
self.clear = function() {
$scope.self.list = [];
};
});
this is a controller written in angular. how can I convert this into angular 2 using EM6.
well upto my knowledge there are not alot of tutorials for the upgradation but yes thetre are few one.
https://angular.io/docs/ts/latest/guide/upgrade.html
http://blog.thoughtram.io/angular/2015/10/24/upgrading-apps-to-angular-2-using-ngupgrade.html
well let me tell you about basic angular2 app.
in angular 1.x our main module is initilize like this
angular.module('app', [])
but in the angular2 our main component started from the bootstraped file like this.
import {bootstrap} from 'angular2/platform/browser';
import {App} from './app';
bootstrap(App,['here global level dependenices....']);
here app is our main component whihc is imported in this bootstrap file. so bootstraped is file our entry point of the app. and
if we want to do some coding stuff like we work in the angular1.x controller here we do the same work in the class file (typescript class)
here i am posting one basic example like this.
import {Component, View} from 'angular2/core';
#Component({
selector: 'app',
templateUrl: "src/app.html",
styleUrls: ['src/app.css'],
directives: [ directives list here....],
})
export class App
{
// stuff you want to do here
}
firstly we have to import angular2 bundles from the systemjs bundles like we imported Component and view in this example from the angular2/core.
there are alot of imports available for the angular2. you can check out here and here

Categories