I'm developing Ecommerce app using ionic-3. The app is in multiple language and i have used ngx-translate for translate language but I'm getting error of translate. I have enclosed error image below. Let me know if you know any solution.
Thank you.
import { TranslateService } from '#ngx-translate/core';
constructor(
private translate: TranslateService,
) {
// console.log(translate.translations);
translate.getTranslation('en').subscribe(res => {
console.log(res);
});
}
Related
I'm trying to learn NestJs by creating a CRUD API.
I've created my controller, module, service etc...
And created a get users/id endpoint. Everything worked fine, and I decided to add some security.
I want to check if the id is not null and is a string. If not, I want to throw an exception (bad request) + console.log a message.
I also want to check if when I look for a user with a good if, the user exists. if not, throw a not found exception.
Here is my service:
async findOne(id: string): Promise<IUser | null> {
if (id === null || typeof id !== 'string') {
throw new BadRequestException('Id must be a string');
}
const user = await this.userModel.findById(id).exec();
if (user === null) {
throw new NotFoundException('No user found for this id');
}
return user;
}
and controller:
#Get(':id')
async find(#Param('id') id: string) {
try {
return await this.userService.findOne(id);
} catch (error) {
if (error instanceof BadRequestException) {
throw new HttpException(
{
status: HttpStatus.FORBIDDEN,
error: 'This is a custom message',
},
HttpStatus.FORBIDDEN,
{
cause: error,
},
);
} else if (error instanceof NotFoundException) {
throw new HttpException(
{
status: HttpStatus.NOT_FOUND,
error: 'This is a custom not found message',
},
HttpStatus.NOT_FOUND,
{
cause: error,
},
);
}
}
}
The problem is when I try a get request with .../users/1111 ,I got a 200 response. And when I try with a good id (a string) but with no user linked, I also get a 200 response.
I don't understand why.. Can you help me please ?
I also want to log the message.
And have you any advices ? Is the right way (standard + elegant) to do ?
Thanks guys ;)
In your code you are checking id to be of a type string and not null. Technically any param is a string, so even 1111 becomes "1111". You can verify that by logging it like so console.log({ id }) (expected result: { id: "1111" }).
For the validation I would suggest to follow the documentation on validation pipes: NestJS documentation.
TLDR;
The following code will add a global pipe to validate payloads
app.module.ts (copied from NestJS | Pipes)
import { Module } from '#nestjs/common';
import { APP_PIPE } from '#nestjs/core';
#Module({
providers: [
{
provide: APP_PIPE,
useClass: ValidationPipe,
},
],
})
export class AppModule {}
To make it work you will need to have class-validator and class-transformer installed, so run:
npm i --save class-validator class-transformer
Then declare a class that will serve as a blueprint of a DTO (Data Transfer Object), like so:
import { IsString, IsNotEmpty } from 'class-validator';
export class IdDto {
#IsNotEmpty()
#IsString()
id: string;
}
Then in your controller use the IdDto:
#Get(':id')
async find(#Param() { id }: IdDto) {
...
This already should be enough to have a basic validation. Moreover, this will convert the payload to a format that you expect (or fail and throw validation error). It is done via plainToClass method exposed from class-transformer. So there won't be any surprises with JavaScript type coercion like "1" + 1 = "11".
If you need to format your exceptions (or enrich them with additional data) you can use exception filters. There is a nice documentation about it in the official documentation.
Hope that helps!
I'm using the cordova in-app-browser plugin. One Page I get back is just a bunch of JSON-Data which i want to store inside my IONIC 5 Project. I could'nt figure out yet how to receive the Data and transfer it to the App yet with the Plugin. Is there such a possibility?
Thank you
To transfer data using InAppBrowser you can pass It by parameters, and also to receive the date you get it from parameters. Follows a small example:
Short way sending data on Page1.ts:
const dataToSend = `/${this.dataOne}/${this.dataTwo}`;
let finalUrl = `https://app-example.io` + dataToSend;
this.inAppB.create(finalUrl, '_system');
Receiving data on Page2.ts:
import { ActivatedRoute } from '#angular/router';
constructor(
private actRoute: ActivatedRoute
){}
ngOnInit() {
this.actRoute.paramMap.subscribe( params => {
console.log('Params => ', params);
if (params) {
let dataReceived = [params['params']['dataOne'], params['params']['dataTwo']];
console.log('dataReceived => ', dataReceived);
}
}
}
Please, adapt it to your code and variables as it is just a short example.
I'm very new to Ionic and JS programming in general so please forgive my ignorance. I've been able to get data from other REST providers I've setup and have the updated values display fine. Pretty much copied the code from some other working functions. This time, no matter what I try, nothing will update.
Provider:
return new Promise(resolve => {
this.http.post(this.apiUrl)
.subscribe(res => {
resolve(res);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
this.error = {"text":"App error occured."};
console.log('Client-side error occured.');
} else {
this.error = {"text":"Cloud server error occured."};
console.log('Cloud server error occured:'+err);
}
return this.error;
});
});
}
HTML:
<ion-item>
<ion-label stacked>Make</ion-label>
{{vesselData?.make}}
</ion-item>
Function:
vesselData = {"make":""};
updateVesselInfo() {
const data = JSON.parse(localStorage.getItem('userData'));
this.vesselProvider.getVesselData(data.userData.sim).then(vData => {
this.vesselData = vData;
}).catch(console.log.bind(console));
}, (err) => {
console.log("Vessel: ".err);
});
If I log the data returned from the provider in the .then(), it shows the provider returned the correct data. However, it's not updating any of the vesselData variables. Any idea where I'm going wrong here?
So modern way is to provide method in your provider that returns Observable and then in your component you just call this method and subscribe to it to obtain data:
In your provider:
getVesselData() {
return this.http.post(this.apiUrl)
.pipe(
catchError(this.yourErrorHandlerInsideProviderHere)
)
}
Now in your component:
vesselData = {"make":""};
updateVesselInfo() {
this.provider.getVesselData().subscribe( vesselData => {
this.vesselData = vesselData;
})
}
So ideal is to keep error handling inside provider here and within component your methods should be light weight.
This example should work for you as long as you are on Angular 4.3+ using modern HTTP module that comes with it.
Update:
Please ensure you properly bind to template. Here is example:
https://stackblitz.com/edit/ionic-wqrnl4
I skipped the rest call (http), but the principle is the same.
I am creating a chat page in my ionic application and I would like to know when the get request changes. I am also OK with doing this all off of an interval, but I can’t find a good example on how to do it. I would prefer to not have to have the user refresh the page to see if a new chat message has appeared. I am newer to observables and have not seen this done with the remote data source and the HTTP package. My data is already JSON so that's why it's not mentioned at all. Thanks!
Chat.ts
import { Component, ViewChild ,ElementRef} from '#angular/core';
import { IonicPage, NavController, NavParams, Events, Content } from 'ionic-angular';
import { ChatProvider } from "../../../../../providers/chat/chat";
import { Observable } from "rxjs/Observable";
export class ChatShowPage {
public id:string;
public items: Observable<ChatMessage[]> = [];
constructor(navParams: NavParams, private chatService: ChatProvider, private events: Events,) {
this.id = navParams.get('id_convo');
}
getMsg() {
return this.chatService.getMsgList(this.id).subscribe(res => {
this.items=res;
console.log(this.items);
});
}
}
Provider.ts
getMsgList(id): Observable<ChatMessage[]> {
const msgListUrl = this.base_url + 'user/account/chat/show/' + id;
console.log('getMsgList - ' + msgListUrl);
return this.http.get<any>(msgListUrl,
{headers: new HttpHeaders({'Content': 'application/json','Accept': 'application/json','Authorization': 'Bearer ' + localStorage.getItem('tk') })});
}
You want to use Events to update your component
In this particular example, you could use:
ionViewWillLeave() {
// unsubscribe
this.events.unsubscribe('chat:received');
}
ionViewDidEnter() {
//get message list
this.getMsg();
// Subscribe to received new message events
this.events.subscribe('chat:received', msg => {
this.pushNewMsg(msg);
})
}
In your provider.ts your getMsgList function should emit the chat:received event as such:
this.events.publish('chat:received')
Then in your pushNewMsg function, you would do some safety checks and then push the new message into the array which you can display with an *ngFor directive.
There are two famous ways to make chat module via web(including ionic).
Polling
WebSocket (Event-driven)
Polling
: If you make simple or personal chat application and want to keep current code structure, then you'd better use polling pattern which merely repeat request with some interval. In addition, for better polling, please consider HTTP Long Polling
setTimeout() with recursion or setInterval() can be options.
WebSocket (Event-driven)
: If you make commercial application or application with lots of users, then you have to use Event-driven pattern. For using this pattern, both of server-side work and client-side work are needed. If you use node.js as server-side framework, then I recommend to use Socket.IO.
First of all, I'm not a newbie to Meteor, but after the latest Meteor updates I have to re-study the framework, and now I'm having trouble using Meteor subscription on the client side.
To be specific, I have subscribed a collection on the client side, however when I try to refer to it the browser console reported the error:
Exception in template helper: ReferenceError: Chatbox is not defined
Here's the structure of my code:
imports/api/chatbox/chatboxes.js
// define the collection
export const Chatbox = new Mongo.Collection("chatbox");
imports/api/chatbox/server/publication.js - to be imported in server/main.js
import { Meteor } from "meteor/meteor";
import { Chatbox } from "../chatboxes";
Meteor.publish("chatbox", function(parameter) {
return Chatbox.find(parameter.find, parameter.options);
});
imports/ui/chatbox/chatbox.js - page template to be rendered as content upon routing
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict';
import './chatbox.html';
import './chatbox.css';
Template.chatbox.onCreated(function bodyOnCreated() {
this.state = new ReactiveDict();
// create subscription query
var parameters = {
find: {
// query selectors
permission: "1001",
},
options: {
// query options
}
};
Meteor.subscribe("chatbox", parameters);
});
Template.chatbox.helpers({
canAddMore() {
// Chatbox collection direct access from client
return Chatbox.find().count() < 3;
},
});
I'd appreciate if you can help me with this issue. Thanks all for taking your time reading my question!
Regards
You need to import Chatbox in imports/ui/chatbox/chatbox.js:
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict';
import { Chatbox } from "../chatboxes"; // correct this path
It's undefined right now because it hasn't been imported.