panelChange binding a value on the panel Angular 6 - javascript

Overview
Im learning Angular and JHipster trying to get the id of an objet in a collection.
but I can't get the event click to work on the panel also a I can't use the panelChange event on the panel itself.
Is a DAFO analysis so i need the id to get the elements
My thoughts
think im donning wrong the binding or im using a different event
this is in the TypeScript side of the component
ngOnInit() {
this.activatedRoute.data.subscribe(({ planEstrategico }) => {
this.planEstrategico = planEstrategico;
this.idPlan = planEstrategico.id;
this.cargarAnaliziFoda(this.idPlan);
});
}
cargarElementosFoda(id) {
console.log(id);
}
first I try this
<ngb-panel
(click)="cargarElementosFoda(diagnosticoFoda.id)"
*ngFor="let diagnosticoFoda of diagnosticoFodas"
>
dint work so I try this
<ngb-panel
(panelChange)="cargarElementosFoda(diagnosticoFoda.id)"
*ngFor="let diagnosticoFoda of diagnosticoFodas"
>
also don't work
I read only works on the ngb-accordion
but the problem is not all the panels are for DOFA just one or two.
Questions
Best way to get the id of my collection with click event?
Alternative ways to get the id? maybe on the typescript side of the
component
Notes
im really new on Angular, TypeScript and Jhipster please if I miss something important let me know it on the comment I will added to the question.

Related

How to insert tabledata into table with vue.js?

I'm working in a project with vue-cli and they want me to generate a listlike view (pun intended) onto data from the database.
I've never really worked with vue. 4 months ago I was given some time to find my way into it, but then I had to work on our lumen-driven backend api and so I forgot most of the stuff. And besides that, I really find vue utterly confusing.
So I need to do this step by step since I dont have loads of time at hand to throughly learn the framework before actually producing usable results.
I have the following template:
<template>
<div>
<h1>myList</h1>
<table id="testTable"></table>
<button class="button" v-on:click='fetchList'>myButton</button>
</div>
</template>
<script>
import store from "../store/store";
import { USER_FETCHLIST } from "../store/actions/user";
export default {
data () {
return {
}
},
methods: {
fetchList: function(){
var test = store.dispatch(USER_FETCHLIST).then((res)=> {
console.log(res)
document.getElementById("testTable").InnerHTML = res
})
}
}
}
</script>
<style>
</style>
The fetchList() successfully fetches the data from the DB. But I cant insert anything into my table element, at least not this "javascript-way" which I tried in the above code.
For example, when I try to input this string: <tr><td>1</td><td>2</td></tr> into the table element, nothing happens.
I learnt about v-bind and all this stuff, but I really don't know how to implement it here.
I also must emphasize that I absolutely want to avoid building this component from subcomponents.
The "inheritance" in vue.js is pretty different from the usual inheritance in programming and I really tried to get my head around it, but I just cant make anything useful with it in my relatively short timeframe.
So I need to have all the JS and html in place in this component.
Can anyone give me a hand in propery binding the prefabricated HTML-String to the table element?
Thank you!

Refresh the parent component view in Angular 4

I have got 2 components, let's say, Component A is a list view and Component B is a details view. Each row from the list view is clickable and will redirect to Component B upon clicking.
Component B allows editing and saving the details. I have added a Back button to Component B to allow me to go back to the list view.
But the problem I am having is that I can't see the updated list view and have to manually refresh the browser, and then I can see the updated list there.
I have tried directly using window.location and it works but really I don't prefer this approach.
public back() {
window.location.assign('/listview');
}
I wonder if there's any better way to solve this problem?
Update:
public onSelected(model: MyModel) {
const detailsViewUrl = `/detailsview/${model.id}`;
this._router.navigateByUrl(detailsViewUrl );
}
You can just emit an #Output EventEmitter with a method on Parent that looks in the event for a change with a variable stored in the component like this:
#Output someOutput: EventEmitter = new Event Emitter<any>;
HTML:
<b-component (someOutput)=getOutput($event)></b-component>
AComponent:
getOut(event){
let output = event;
if(this.something != output){
this.ngOnDestroy(); // or something that you can use to make it
}
That should work as intended.
It sounds like this is an issue with Angular's change detection when changing the contents of an array. See here:
Angular 2: How to detect changes in an array? (#input property)
The solutions in this questions should work but an easy way I have used in the past to force changes in an array to be recognised by Angular is to reassign the array after making the changes:
myArray = [...myArray];
use following routing fuction on back button click
public back() {
this._router.navigateByUrl('/listview')
}
or
public back() {
this._router.navigate('/listview')
}
Try this,
Just called the list view again internally and hit db at same time so updated values will be displayed in the list view.
calling the route by using below:
this.router.navigate(['/listview']);
Seems like a change detection issue, there are some ways to manually trigger change detection like so:
Inject ChangeDetectorRef.
Call it when you go back like so:
public back() {
ChangeDetectorRef.detectChanges()
}
Refer to this: Triggering change detection manually in Angular

Angular 2: Template not updating after http service update

I'm still trying to learn ng2 so I'm sure this is a common noob problem but none of the solutions I found online helped. anyone know what my problem is?
I have a service with the getEventList() method as an observable
getEventList(): Observable<any>{
return this.http.get('./assets/data.json')
.map(response => response.json());
}
I subscribe to it in my component
ngOnInit(){
this.eventService.getEventList()
.subscribe(events => {
this.zone.run(()=>{
this.events = events;
console.log(this.events)
});
});
}
My template just tries to output the events variable in json format
<p>
{{
events | json
}}
</p>
As you can see I'm assigning the value of events to a local variable in a zone.run() callback. Still not seeing my template update. I've also tried ApplicationRef.tick and ChangeDetectorRef.detectChanges() but neither seem to detect my changes.
Console.log call does confirm that the data was updated. Any click handler fired on this component also seems to update the view.
Anyone know what I'm doing wrong here? Did I post enough of the code to get some advice? Let me know what else you would like to see.
This should do it, assuming you haven't assigned a value to this.events before calling getEventList() method:
<div *ngIf="events">
{{ events | json }}
</div>
The seed was setting the ChangeDetectionStrategy to OnPush. Setting this to default solved my problem.

Is there a way to "watch" an IndexedDB record so I can respond when it's been changed?

I am building an Angular + TypeScript application that uses IndexedDB for storing data locally.
I have an Angular directive that sets the value of a scope variable to be some data that was returned from an IndexedDB request. It's pretty simple and does something like:
Directive A:
// getGroup() is making the requests to IndexedDB:
this.dataService.getGroup().then((groupOne) => {
this.scope.items = groupOne.items;
});
The view for my directive loops through each of these items:
<div ng-repeat="item in items">{{ item }}</div>
I have another Angular directive (let's call it Directive B) that is updating/inserting the items associated with groupOne.
Directive B:
groupOne.items.push("a new item");
this.dataService.updateGroup(groupOne).then(() => {
// groupOne has been changed!
// how can I let Directive A know about this, so Directive A can update its scope.items?
});
Of course, Directive A does not know about the changes Directive B made to groupOne unless it does another request. And therefore, my view is "static".
I know I could wrap Directive A's IndexedDB request into an interval and be checking for updates, but that seems like a strange way to solve this problem.
Is there a way with IndexedDB to be notified of this change? Is there something Angular provides that could help with this (something similar to $scope.$watch()) ?
It's not quite what I wanted (which is why I accepted dgrogan's answer), but in case anyone who stumbles upon this question is curious about what I ended up doing:
Manually broadcasting a custom event whenever I change groupOne (or anything else I care about) solves my problem for now.
I used $scope.$broadcast() from a controller (that's managing
a few interactions between directives) to let Directive A know about
the change Directive B made using $scope.$on().
This article was really helpful: http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
There is not yet a way to do this with pure IndexedDB but it is being prototyped. The name is "Observers". You can try to use the polyfill if you are so inclined.

How to redirect to different controller?

I have an application in ASP.MVC. The requirement is that I select a person from a list of people and click 'Info' and it should load the details of the person in that page. I have the Info controller and everything works fine if I go to the Info page from a different controller. In the page I am trying to make it work with JavaScript and it doesn't seem to take me to the desired page but to a different controller.
I have a ToDoList controller and in the .cshtml I have this code on click of the Info link.
function DoInfo#(i.ToString())() {
$("#sessionid").val("#Model.cSessionId[i]");
alert("hey");
$("#PageController").val(66);
$("#formID").submit();
}
I go to the ToDoList controller to do the redirection like this
if (viewModel.PageController == 66)
{
pass = new PassingData();
pass.personid = TSSessionService.ReadPersonId(viewModel.SessionId);
TempData["pass"] = pass;
return RedirectToAction("Index", "Info");
}
It never goes there and instead goes to a different controller. I cannot seem to find how they are linked and why is it not going back to controller where the Info link button is i.e. back to the ToDoList controller.
Let me know if it is not clear and I will try to explain again and I will give any other details.
I guess I'm confused as to why you are doing this as a combination of form and JavaScript. Are there other properties that you need to pass along that you are not posting above? Why do you need to use JavaScript to do this if you are just returning a new view?
You indicate in your post that when a person is selected from a list you need to go to a controller and display a view. This seems fairly straightforward, and I would like to suggest simplifying the problem.
Start with this: change your link to not use a form or JavaScript. Just make it a link. If it is text, you can use #Html.ActionLink() and even pass in the parameters you need.
If you're not displaying text, just use #Url.ActionLink() in your href property of the anchor you're wrapping your element with. Both of these allow you to leverage routing to ensure the correct path is being constructed.
If the controller that you are trying to get to has access to whatever TSSessionService is, then you don't need to pass through the TempData["pass"] you are trying to push through, so it makes it cleaner in that way as well.
If you do need to submit a more complicated value set, I would recommend coming up with a generic .click() event handler in jQuery that can respond to any of the clicks, bound by a common class name. You can use a data-val attribute in your link and read from $(this).attr('data-val') in your handler to store/fetch other important info. This allows you to more easily build up an object to POST to a controller.
Hope this helps some, but if I'm missing a critical point then please update the question above.

Categories