Upload search results data in angular with a button click - javascript

I am having a project requirement on Angular. I am using search option where I am able to search data from external api and display user below it when clicking on Add button. I tried implementing using angular primeng autocomplete.
But problem is that as per the screenshot here https://imgur.com/a/wXYqOpM
When I clicked on Upload List, all the user data displayed should be uploaded with a button click (either as file or array). Since I am new to angular, can you help me to find a suitable solution for the same?
Thanks in advance
Patric

There's a bit more input needed in order to properly, entirely answer your question. I'll just make a couple assumptions to do so.
I suppose that you're having an array of patients/users in your .ts file and display that data in your .html using data interpolation. Something like this:
upload-list.component.ts:
...
public userList = ['Patient 1', 'Patient 2', 'Patient 3']
...
upload-list.component.html:
...
<your-list-display>{{ userList }}</your-list-display>
<button (click)='sendData()'>Upload list</button>
Eventually, all you need to do is inject the HttpClient (imported from #angular/common/http) into your component's constructor and use it (preferably in a service, read up in the angular.io docs for that specifically, how to share data between components etc).
Roughly outlined, something like this shall work:
upload-list.component.ts:
import { HttpClient } from '#angular/common/http';
...
export class UserList {
constructor(private http: HttpClient) {}
public sendData(): void {
this.http.post<any>(apiURL, this.userList).subscribe(result => {
... // do something with the result from your HTTP request.
}, error => {
... // handle error as wished
});
}
}
Hope that'll help - Regards
EDIT - moved API call into function which'll be called upon button click

Related

Ionic 6 and Angular navigates to route which is already in history

I am using Ionic 6 and Angular 12 and I have couple pages in the app flow. I wen to page_4 and when I checked my DOM structure it looks like:
<ion-router-outlet>
<page_1></page_1>
<page_2></page_2>
<page_3></page_3>
<page_4></page_4>
</ion-router-outlet>
After page_4 I want to navigate to new page_2 and send some data via state object:
this.router.navigateByUrl('/page_2', { state: {dataHasChanged: true} });
I expected:
Ionic will create again new <page_2></page_2> tag into DOM bellow <page_4></page_4>
I can retrieve state data like I usually do:
this.router.getCurrentNavigation().extras?.state?.dataHasChanged
But result is different:
App back to the previous <page_2></page_2> and my DOM structure looks like:
<ion-router-outlet>
<page_1></page_1>
<page_2></page_2>
</ion-router-outlet>
this.router.getCurrentNavigation().extras is null and cannot see my data here. But I can see state data into windows.history.state object
Can someone please explain me why this happened or at least refer me to some valuable documentation ?
If you enter a page that has already been loaded, it will not load again, or at least, not always.
You can celar or update the content of the page inside ionViewWillEnter.
check this
add it in your page.ts
ionViewWillEnter() {
...
}
To solve the problem of navigation extras empty you can share data with a Service like this. It's not the cleanest way but it works
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class DataShareService {
private __dataDict = {};
setData(key: string, data: any) {
this.__dataDict[key] = data;
}
getData(key: string) {
return this.__dataDict[key];
}
}

ag-grid showing a custom overlay

Is there a way to show other custom overlays based on program logic? E.g. I'd like to have an "Error" overlay in addition to "No rows" and "Loading"
I have reviewed and implemented the customized "loading" and "no rows" overlays as described here: https://www.ag-grid.com/javascript-grid-overlay-component/ Super easy, really clean implementation.
Ideally, the api of showing an overlay could take a parameter that specifies which template to use...
You could have an overlay component which renders the different overlays based on the parameters you send.
You could accomplish this using ngIf in your template and rendering different html based on the parameter.
I don't think there is currently any other way to do it through Ag-Grid.
You can send it parameters for example by doing the following
[loadingOverlayComponent]="loadingOverlayComponent"
[loadingOverlayComponentParams]="loadingOverlayComponentParams"
this.loadingOverlayComponent = "customLoadingOverlay";
this.loadingOverlayComponentParams = { template: "overLay1" };
and in your component
export class CustomLoadingOverlay implements ILoadingOverlayAngularComp {
private params: any;
agInit(params): void {
this.params = params;
if (params.template == "overLay1") {
// do something
}
}
}
I know its not the best way to get this done but that works till we get something implemented into Ag-Grid

Ember: Getting model data in the controller

I am new to ember and I am building a DnD character sheet to learn and practice. Right now I am having a lot of trouble getting access to model data in a controller. After hours and hours of reading related posts it is just not clicking and I think I am misunderstanding what I am passing to the controller.
Basically what I am trying to do is grab data from a model so I can do calculations on them and then display the results of those calculations on the page.
Here is my transforms/router.js:
Router.map(function() {
this.route('characters', { path: '/'})
this.route('new', {path: 'new'});
this.route('view', {path: '/:character_id'});
});
So here I am trying to pull up the view page which has the URL of the character id. Next here is my route for the view page:
export default Route.extend({
character: function () {
return this.store.findRecord('character', id)
}
});
So this is finding the record of the character with the id I pass. My link looks like this and is coming from a component:
<h5 class="card-title">{{#link-to 'view' id}}{{name}}{{/link-to}}</h5>
Now I have my controller for the view page, which looks like this:
init(id){
let character = this.get('character')
}
When I try to log character, it is still undefined. When looking ember information in dev tools it seems the page is getting the information from the model after I refresh the page, but I just can't seem to be figure out how to grab that info in the controller itself to manipulate it.
I've been trying to figure this out for quite a while now, and its getting pretty frustrating. I currently have a work around where I do the calculations beforehand and just store all the calculated results in the model as well, but while I am learning I would like to understand how this works. Thanks is advance.
Edit: As pointed out in comments below I was missing let when defining character.
Your model hook seems wrong. You're using id but never define it. Probably what you want is more like this:
character(params) {
return this.store.findRecord('character', params.character_id);
}
Next your init hook makes no sense:
init(id){
let character = this.get('character')
}
First there is no id passed to the init hook. Second you're missing this._super(...arguments) which should always be called when you override init.
Last is that your controller is first created and later populated with the model. Also the model is populated as model property, not character.
So you could place this in your routes template and it will work:
This is character {{model.id}}
Or if you want to change something before you pass it to the template you should use a computed property in your controller:
foo: computed('model.id', function() {
return this.get('model.id') + ' is the id of the character';
}),
However for this code to run you need to use. The easiest way to use it is to put it into your template:
{{foo}}

populate FormBuilder from a service in Angular2

I have an Angular2 model that I'm populating via a service. I would like to use this model to then populate my form (built from FormBuilder) so my users can edit the data.
Here is what I am currently doing, but I get errors for fields that exist in my model that are not being exposed in my form.
...
ngOnInit(): void {
this.buildForm();
this.get('1');
}
get(id: string) {
this.myModelsService.get(id)
.subscribe(
d => {
this.myModel = d;
this.myForm.setValue(d);
},
error => console.log(error)
);
}
This works, however I get errors like Cannot find form control with name: incidentTimeStamp.
Should I be first deleting attributes that I know do not have corresponding form controls? Or is there a better way to do what I am trying to do?
Being able to populate fields for edit seems like a pretty basic building block, and this seems like it is way harder than it should be.
The solution is to use FormGroup.patchValue()
FormGroup.setValue() does strict checks, while FormGroup.patchValue() does not.

Why is Angular 2's template not updating from calls outside an angular zone?

I thought I would create a very simple login form with component-bound username and password properties that would run through the following steps:
Submit credentials with a fetch() call
THEN obtain the Response result object's JSON content
THEN check that content for the result of the server-side check
If the credentials were wrong, it would change a component property that would tell Angular to apply a class to the username and password inputs to make them red temporarily (using setTimeout to change that back)
The problem I ran into is that Angular would not correctly apply the class, and I wasn't sure why. I decided to create a simplified test project to narrow down the problem and ended up with the inclusion of system-polyfills/when.js being cause.
This code goes through 1, 2, then 3, and sets that both in the component property and outputs it to the debug console. Angular correctly renders the component property unless system-polyfill is included, in which case it will stop at 1 and never change it to 2 or 3, even though the console shows that the property is in fact changed:
export class App {
private stateIndicator:string = "0";
public showState(state:string) {
console.log('State: ' + state);
this.stateIndicator = state;
}
public showFetchProblem() {
this.showState('1')
fetch('http://www.google.com/robots.txt',{mode:'no-cors'}).then((response:any) => {
this.showState('2')
response.text().then((value) => {
this.showState('3')
});
});
}
}
I created the following Plunker to demonstrate this behaviour: http://plnkr.co/edit/GR9U9fTctmkSGsPTySAI?p=preview
And yeah, the obvious solutions are:
Don't manually include system-polyfills, or
Manually include a differeny Promise polyfill before SystemJS if you need it
But I'm still curious why this is happening, and hopefully somebody can shed some light on this (and possibly help to resolve the base issue).
Edit: The original title of this was Why is Angular 2's template rendering misbehaving when using system-polyfills (when.js). Thanks to Thierry and Günter for contributing and pointing out that Angular 2's use of zones is at play here. For anybody who comes across this in the future, here are two excellent articles that explain zones in further detail and will enhance your understanding of this scenario should you run into it:
http://blog.thoughtram.io/angular/2016/01/22/understanding-zones.html
http://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html
Promise polyfill provides a custom implementation of Promise that seems to be executed outside the scope of Angular2 (i.e. not in a zone).
If you execute your code explicitly within a zone managed by Angular2 (with the NgZone class), it works when the system-polyfill.js file is included.
Here is a sample:
constructor(private zone:NgZone) {}
public showFetchProblem() {
this.showState('1')
this.zone.run(() => {
fetch('http://www.google.com/robots.txt',{mode:'no-cors'}).then((response:any) => {
this.showState('2')
response.text().then((value) => {
this.showState('3')
});
});
});
}
See the corresponding plunkr: http://plnkr.co/edit/EJgZKWVx6FURrelMEzN0?p=preview.
update
Not sure about the explanation anymore but the workaround works. But I think there is some other underlying issue.
See also https://github.com/angular/angular/issues/7792#issuecomment-211217775
original
I assume the problem is caused by fetch not being patched by Angulars zone
To work around make the code execute inside Angulars zone manually
export class App {
constructor(private zone:NgZone) {}
private stateIndicator:string = "0";
public showState(state:string) {
console.log('State: ' + state);
this.stateIndicator = state;
}
public showFetchProblem() {
this.showState('1')
fetch('http://www.google.com/robots.txt',{mode:'no-cors'}).then((response:any) => {
this.showState('2')
response.text().then((value) => {
this.zone.run(() => this.showState('3'));
});
});
}
}
Plunker example

Categories