Ionic 2 : Moving config properties into the bootstrap - ionic-framework

Before beta.8 version, I have a working service which acts as my HTTP service.
#Page({
templateUrl: 'build/pages/log-in/log-in.html',
providers: [httpService]
})
...
this.httpService.testService("VariablesToPass").subscribe(
data => {this.results = data.results; console.log(data);},
//err => this.logError(err),
err => console.log(err),
() => console.log('Invoked Login Service Complete')
);
After the new version, configs have to move into the bootstrap, thus in my js i implemented the following :
#Component({
templateUrl: 'build/pages/log-in/log-in.html'
})
export class LoginPage {
...
}
ionicBootstrap(LoginPage, [httpService], {});
in which throws me errors like:
Using
ionicBootstrap(LoginPage, [httpService], {});
or
ionicBootstrap(LoginPage, [httpService]);
gives the same error result.

ionicBootstrap must be used only in your former #App, not in a former #Page, inject httpService there, not in LoginPage.
In your LoginPage leave the provider registration. Also, beware of your naming convention, it doesn't look right, you are using the same name for the service and its instance. It should be like this:
#Component({
templateUrl: 'build/pages/log-in/log-in.html',
providers: [HttpService]
})
class LoginPage {
constructor ( private httpService : HttpService) {}
}
also, it's beta 8, not RC

Related

Can't use cordova-plugin-file on ionic 4

I am trying to use ionic 4 and cordova-plugin-file to get files from phone but it trows an error;
When i do console.log(cordova.file) like in the doc it shows cordova does not have property 'file'.
When i do
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail); it show 'requestFileSystem' not a property of window.
even if i do window.cordova it trow thesame error.
and unlike ionic 3 here if i add File to providers it trows an error as well
Please what is it i'm doing wrong?
Here is my ** home.page.ts**
import {Component} from '#angular/core';
import {Platform} from '#ionic/angular';
import {File} from '#ionic-native/file';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(public platform: Platform) {
platform.ready().then(() => {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
console.log(fileSystem)
}, function(error) {
console.log(error);
});
});
}
}
For Ionic 4 you should add 'ngx' at the end of the import.
Like this,
import {File} from '#ionic-native/file/ngx';
Make sure to add it to the providers list of your module file, and also inject it to the constructor of the class where ever you are using the plugin.
Reference https://ionicframework.com/docs/native

Using mongodb-stitch library in Angular 4

Im been trying the MongoDB Stitch service in Angular, so far Im able to use the service. However, the only way I could connect to the service is by including the js library hosted in AWS on the html page.
There is a mongodb-stitch npm package available and there are sample pages on mongodb tutorial on how to use it. But this is a pure JS library (no TS support) and I have tried several ways (using require, installing typings of the lib (not available), using #types) to no avail.
Anyone tried this on Ng4? Would love to have the steps you did to use the 'mongodb-stitch' package the create a service.
The other answer suggests instantiating a new instance of StitchClient which is something that MongoDB have explicitly advised against in the Official API Documentation - and with reason, since there is a factory method available for that purpose. So, (after installing mongodb-stitch), the following code would help you get started in component.ts
import { Component, OnInit } from "#angular/core";
import { StitchClientFactory } from "mongodb-stitch";
let appId = 'authapp-****';
#Component({
selector: "app-mongo-auth",
templateUrl: "./mongo-auth.component.html",
styleUrls: ["./mongo-auth.component.css"]
})
export class MongoAuthComponent implements OnInit {
mClient;
ngOnInit() {
this.mClient = StitchClientFactory.create(appId);
}
And you can then use this for whatever purpose you want, such as for implementing sign-in with Google
gLogin(){
this.mClient.then(stitchClient => {
stitchClient.authenticate("google");
})
not sure whether the question is still relevant considering it was asked two months ago but anyway...
As you pointed out you can use
npm install --save mongodb-stitch
to install the package and since there is no TS binding you can declare the stitch library as any
For example:
declare var stitch: any;
export class MyService implements OnInit {
db;
client;
ngOnInit() {
this.client = new stitch.StitchClient('<check the stitch app page for proper value>');
this.db = this.client.service('mongodb', 'mongodb-atlas').db('<the db name goes here>');
this.client.login();
}
save() {
this.db.collection('<collection name>').insertOne({key : 'value'}).then(() => console.log("All done"));
}
}
the previous answers are functional, but i wanna share a example using a service injectable.
service.ts
import { Injectable } from '#angular/core';
import { Jsonp, URLSearchParams } from '#angular/http';
import { StitchClientFactory } from "mongodb-stitch";
import 'rxjs/add/operator/map';
#Injectable()
export class Service {
constructor(private jsonp: Jsonp) { }
client;
connect(){
this.client = new StitchClientFactory.create("App ID"); // Slitch apps > Clients > App ID
this.client.then(stitchClient => stitchClient.login())
.then((stitchClient) => console.log('logged in as: ' + stitchClient))
.catch(e => console.log('error: ', e));
}
all() {
this.connect();
return this.client.then(stitchClient => {
let db = stitchClient.service('mongodb', 'mongodb-atlas').db("database Name"); // Slitch apps > mongodb-atlas > Name database.Collection
let itemsCollection = db.collection('name collection'); // Slitch apps > mongodb-atlas > Name database.Collection
console.log(itemsCollection.find().execute());
return itemsCollection.find().execute();
})
.then(result => {return result})
.catch(e => console.log('error: ', e));
}
}
after make the previous file, you must create a module to receive the data, so:
module.ts
import { Component, OnInit, Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { StitchClientFactory } from "mongodb-stitch";
import { Service } from 'service'; // previous code
declare var stitch: any;
#Component({
template: '
<ul class="demo-list-icon mdl-list">
<li class="mdl-list__item" *ngFor="let item of data | async">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">{{propiedad.nombre}}</i>
</span>
</li>
</ul>
'
})
export class MainComponent implements OnInit {
data: Observable<[]>;
constructor(private Service: service) {
}
ngOnInit() {
this.propiedades = this.Service.all();
}
}
important, you don´t must forget to add service on module.ts intitial declarations.
mongodb Atlas
mongodb-stitch vía NPM
Documentation mongoDB Stitch.
Sure!

Angular 2 Passing object between routes

Trying to find the answer on how to pass a common object between routes.
I have a service which store socket.io
I need to have access to that socket service across my whole site so I can listen for emits.
I have a route.ts file and I am not sure how to initialise a socket service in the root then pass it to the route when needed.
I have read the docs and I am trying to use data like below in my route.ts file:
const routes: RouterConfig = [
{ path: '', component: AppComponent },
{ path: 'function1', component: Function1Component, data: { socket: socket }},
];
However I dont know where to declare the socket service.
Thanks
In your case you are trying to pass some function reference(which is going to return object/promise/observable) from data option of route, so that would not work by passing it in data option because it does stringify the data when you ask for data by doing this.routerData.get('socket').
I strongly recommend to use resolve option of route here. resolve method would return promise/observable
Code
#Injectable()
class SocketResolver implements Resolve {
constructor(private socketService: socketService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
return this.socketService.connection();
}
}
const routes: RouterConfig = [
{ path: '', component: AppComponent },
{ path: 'function1', component: Function1Component,
resolve: { socket: SocketResolver }
}
];
Doc Link
you should not involve routing in this.
just create a service: https://angular.io/docs/ts/latest/tutorial/toh-pt4.html
SocketService.ts
import { Injectable } from '#angular/core';
#Injectable()
export class SocketService {
...
}
and inject that service in your component or other services via the constructor:
constructor(private socketService:SocketService) { }
plus you make sure your service is intialized in the bootstrap process:
bootstrap(AppComponent, [
SocketService,
... ]);
on bootstrap, angular will create a single instance of your service which will be injected into every component which has it in its constructor, therefore you have access to the same socket service from everywhere you want.

Angular2 custom validator not called

I have written a custom validation directive like that:
const DURATION_VALIDATOR = new Provider(
NG_VALIDATORS,
{useExisting: forwardRef(() => DurationDirective), multi: true}
);
#Directive({
selector: '[ngModel][duration], [formControl][duration]',
providers: [{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DurationDirective),
multi: true }]
})
export class DurationDirective implements Validator{
constructor(public model:NgModel){
console.error('init')
}
validate(c:FormControl) {
console.error('validate')
return {'err...':'err...'};
}
}
My Html looks like this:
<input
type="text"
[(ngModel)]="preparation.duration"
duration
required
>
My problem is that while the validator is initialized, i.e. 'init' is logged to console, the validate function is never called, i.e. 'validate' is never logged to the console, when typing into the input field. Since the validator is initialized, I assume that I "wired" up everything correctly. So what is missing?
My best bet is that you haven't bootstraped Angular with regards to forms:
import { App } from './app';
import { disableDeprecatedForms, provideForms } from '#angular/forms';
bootstrap(App, [
// these are crucial
disableDeprecatedForms(),
provideForms()
]);
You can see this plunk - it does output "validate" to the console.
I forked and improved #batesiiic 's plunk: https://plnkr.co/edit/Vokcid?p=preview
validate(c:FormControl) {
console.error('called validate()')
return parseInt(c.value) < 10 ? null : {
duration: {message: 'Please enter a number < 10'}
};
}
The validate() method must return null if the input is valid, otherwise, it returns an object { key: value, ... } where key is the type of error and value can be anything you can use in your template to generate an error message.
The template also contains a div to display the error message if the input is not valid.
Instead of writing the custom validator function as class/component/Directive method,
Writing Custom validator outside the component/Directive should work.
validate(c:FormControl) {
console.error('validate')
return {'err...':'err...'};
}
#Directive({
selector: '[ngModel][duration], [formControl][duration]',
providers: [{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DurationDirective),
multi: true }]
})
export class DurationDirective implements Validator{
constructor(public model:NgModel){
console.error('init')
}
}

Accessing .ENV Properties with Angular2 Typescript and ServerJS

I've been going through the Angular2 Quickstart and tutorials and now I'm trying to get set up pulling data from a live REST Api. I need to pass in authentication parameters with the Api call and everything I'm reading says I should be putting those parameters into the ENV variables.
I can't work out exactly how I should be doing this. I've created a .env file on my local server, I've used NPM to instal dotenv to my project, but none of the examples I can find for how to use dotenv seem to fit with the TypeScript import syntax I'm used to.
Here's my main.ts:
import { } from 'dotenv/config';
import { bootstrap } from '#angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
bootstrap(AppComponent);
And a sample app.component.ts:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Up and running!</h1>
<p>Do not show this at home: {{process.env.TWITTER_CONSUMER_KEY}}</p>
`,
styleUrls: ['style.css']
})
export class AppComponent {
}
Any help would be appreciated. I've been out of the coding loop for a while and this is all a bit new to me.
Bonus question, would I still have the .env file when I go to a live server or does it change?
I think you need to initialize the dotenv config method:
dotenv.config();
I usually use as follow:
import * as dotenv from 'dotenv';
//Later in your code
dotenv.config();
Then you may use your environment variables.
I was having the same problem. Couldn't find a proper solution so I did something like this:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Up and running!</h1>
<p>Do not show this at home: {{twitterConsumerKey}}</p>
`,
styleUrls: ['style.css']
})
export class AppComponent {
public twitterConsumerKey:string;
ngOnInit() {
this.twitterConsumerKey = process.env.TWITTER_CONSUMER_KEY;
}
}