Access an element of subscribed array within component - html

I have an angular project with several arrays in my component which I am accessing directly from the html template via binding. As an example, in my component I have:
public materials = []
This is populated by a service and is accessed in my template as
<section>
<h3>Total Materials</h3> {{ materials[0].materials_aud | number:'1.2-2' }}
</section>
This works fine, however I am performing calculations on this data from within the html and it is becoming very verbose (read: ugly) and difficult to maintain. I would like to be able to access these array elements from within my component as variables and do the calculations within the component (or at least in the template using these variables), however I am unsure how to do this. New to angular and understand the principles of subscribing to observables and casting them to an array but not accessing the array after it is populated. It seems logical that once the array has data, I should be able to access it. I have attempted to access the array via ngOnInit:
ngOnInit {
this.materials_total = this.materials[0].materials_aud
}
but I get an error:
angular Uncaught (in promise): TypeError: Cannot read property
'materials_total' of undefined
Any help/hints appreciated.

Related

Passing object through components using service in angular 2

I have one doubt regarding the components communication using services.
Now I have one parent component, where I am rendering the list array of objects in parent component using NgFor. Whenever I click any particular item, a function gets triggered and specific object is passed in that function.
Then I am using subject and Observables to load that particular data in a child component. Everything looks fine, but here am trying to access that particular item before the triggering of the function, so in console.log am getting the errors like Cannot read property 'movie_id' of undefined)
add an *ngIf to child component regarding the particular data.. that way Angular doesn't try to access the 'movie_id' container object before it exists..
for example, if you have myObj = { ..., movie_id: 'tarzan' } add a *ngIf="myObj"

parse properties of multiple components

I've got a bunch of components of different types, that are created on the fly. When it's time, I would like to parse some state properties of each component and send them to server in JSON format.
for example, each box component has state properties: x, y, width and height. JSON for all the boxes would look like this:
{
projectName:"SOMENAME",
projectDate:"SOMEDATE",
boxes:[
{x:1,y:12,width:123, height:321},
{x:19,y:12,width:773, height:21},
{x:876,y:122,width:3, height:31}
]
}
The order matters. After the box component is created, it is also manipulated, and changes need to be updated in the JSON model.
The way I would do this is to give each component a unique identifier and create a separate data class called Data. This class would have a field projectName, projectDate and array boxes that also stores unique identifier. I would than call JSON.stringify() on the whole object of type Data and send that to server.
Is this the way to go? Does angular have some preferred of solving this issue I described? What method do you recommend?
HTML
<app-box-component *ngFor="let box of boxes"> </app-box-component>
BoxComponent.ts
export class BoxComponent implements onInit{
//state properties that need to be send to server. Collected from every box component.
x:number;
y:number;
width:number;
height:number;
}
The recommended way of dealing with state in Angular app is ngrx store.
In your case when user interacts with a box it can send a message like BoxUpdated and inside ngrx effects you would propagate this change to the server. Your ngrx store could contain all initial box data.

JSON Compatible Output of Whole Object and Their Invisible Properties in Node

const TelegramBot= require('./telegram-bot') // It's currently only local.
var bot = new TelegramBot()
console.log(bot)
// This does not print a complete JSON of the object. It misses stuff like
constructor, method, prototype and super_.
Is there some way or npm module that prints a JSON compatible output of the object?
My only work around so far is console logging it out like this and repeatedly checking the log and printing out another but I think it'll be a lot of easier by having a JSON export and using a JSON online viewer that views like a directory tree.
console.log(`
TelegramBot:
> ${Object.getOwnPropertyNames(TelegramBot)}
TelegramBot.prototype:
> ${Object.getOwnPropertyNames(TelegramBot.prototype)}
TelegramBot.prototype.constructor:
> ${Object.getOwnPropertyNames(TelegramBot.prototype.constructor)}
TelegramBot.prototype.constructor.super_:
> ${Object.getOwnPropertyNames(TelegramBot.prototype.constructor.super_)}
`)
I'm aware functions can't be seen with JSON.parse(). I don't mind if they appear as a string like "Anonymous Function()" or "FunctionWithAName()". Or something like this.
I'm doing this since I'm having another go trying to learn prototypes and I've used util.inherits(TelegramBot, EventEmitter) in the TelegramBot object.
To avoid name clashes between TelegramBot methods I've made and the super class of EventEmitter names. I'd like to keep a clear view of the whole object structure. Or do I not have to worry since they use this variable shadowing thing? If I'm correct it checks the object's instance first, then it's prototype. Not sure if EventEmitter prototype checked first or TelegramBot's.

AdvancedDataGrid - access dataProvider

I have AdvancedDataGrid and I wanted to access dataProvider.getItemAt(i) in function in my view.
I'm not getting any errors nor warning and the code is compiling, but when I run this function I get this error:
Property getItemAt not found on mx.collections.HierarchicalCollectionView and there is no default value.
Why can't I do this? I saw some samples ane people was using this function.
This is how I call it:
var x:Object = _dg.dataProvider.getItemAt(i);
The AdvancedDataGrid's dataProvider is a generic object. That, basically, means the compiler will let any property/method access on it slide without issues.
The HierarchicalCollectionView does not have a getItemAt() method, which is why you get the runtime error. The Hierarchical collection, by nature, contains nested elements I'm not sure how you'd access a single element using a single index.
You probably want to use some form of getChildren() or getParentItem() method to get access to an individual node.
The places where you saw getItemAt() work were most likely using an ArrayCollection.

Return read-only ui component in Flex

In Flex, I want to create some variable that would hold a dictionary of ui components used throughout my application. Ideally, there would be a function in Application component that would return component for id:
public function getComponent4Id(id:String):UIComponent {}
Then I would access component using the following line:
var myComponent:UIComponent = FlexGlobals.topLevelApplication.getComponent4Id("someId");
Now, the only problem is: I want the component returned to be read-only.
It is very convenient to read some properties of myComponent from every corner of application, but I don't want my developers to abuse it and change myComponent.
Is it possible to return a copy of myComponent? Or is it possible to make it read-only somehow?
In the situation you describe, it is not possible to retrieve read only components.
You can create read only variables by implementing get methods without set methods. Something like this:
public var get myValue():UIComponent{
return UIComponent;
}
This would allow you to retrieve the UIComponent instance, myValue, from the component; but you would not be able to set it.
However, this would not prevent people from changing properties on the returned UIComponent unless those properties were also implemented as read only.
I'll add that there is already a method, getChildByName() to retrieve a child component by name. If you have an instance to a parent, you can use this to access the children.
All that said, I'm not sure I completely understand what you hope to achieve; with this functionality.