Link to home
Start Free TrialLog in
Avatar of Dev Me
Dev Me

asked on

RxJS loops

Hi Experts,

   I am trying to loop through json object and filter it into different arrays based on 'group'. Also, trying to assign particular field to a const....I couldn't go beyond

 
 from(Field).pipe(groupBy(fie => fie.group), mergeMap(group => group.pipe(toArray())));

Open in new window


   I would like have this.group1, this.group2, this.gropu3 to have respective Fields after this execution along with this.fieldName1, this.fieldName2 having their respective field values.

  Field object looks like this

 
 Field : [
{ name : fieldname,
  value: FieldValue,
  group: FieldGroup
  }
]

Open in new window

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Do you mean something like this
let filteredArray = [];
data.forEach(item => {
  filteredArray[item.group] = filteredArray[item.group] || [];
  filteredArray[item.group].push(item);
});

Open in new window

Avatar of Dev Me
Dev Me

ASKER

So "item.group" is not a number but a string , how would array take string as index number?
Change the filteredArray to an object
let filteredArray = {};

Open in new window

Now the index acts as a property and you can use strings
Avatar of Dev Me

ASKER

It still gives the same error.  "[ts] Type 'String' cannot be used as an index type."
Avatar of Dev Me

ASKER

Experts any help please?
Please post your full code showing your implementation. My code works here so I need to see how you have interpreted that.
Just implemented it a test Typescript Angular project - works perfectly.
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComonent implements OnInit {
data = [{
    name: 'Test Name 1',
    field: 'Field 1',
    group: 'Group One'
},{
    name: 'Test Name 1',
    field: 'Field 1',
    group: 'Group One'
},{
    name: 'Test Name 2',
    field: 'Field 2',
    group: 'Group Two'
},{
    name: 'Test Name 3',
    field: 'Field 3',
    group: 'Group Three'
},{
    name: 'Test Name 4',
    field: 'Field 4',
    group: 'Group One'
},{
    name: 'Test Name 5',
    field: 'Field 5',
    group: 'Group Four'
},{
    name: 'Test Name 6',
    field: 'Field 6',
    group: 'Group Three'
},{
    name: 'Test Name 7',
    field: 'Field 7',
    group: 'Group Two'
},{
    name: 'Test Name 8',
    field: 'Field 8',
    group: 'Group Four'
},{
    name: 'Test Name 9',
    field: 'Field 9',
    group: 'Group One'
},{
    name: 'Test Name 10',
    field: 'Field 10',
    group: 'Group Two'
}];
    ngOnInit() {
        let filteredArray = {};
        this.data.forEach(item => {
          filteredArray[item.data] = filteredArray[item.data] || [];
          filteredArray[item.data].push(item);
        });
        console.log(filteredArray);
    }
}

Open in new window

Avatar of Dev Me

ASKER

In your latest post, you have used

this.data.forEach(item => {
          filteredArray[item.data] = filteredArray[item.data] || [];
          filteredArray[item.data].push(item);
        });

Open in new window


in your first suggestion you had
let filteredArray = [];
data.forEach(item => {
  filteredArray[item.group] = filteredArray[item.group] || [];
  filteredArray[item.group].push(item);
});

Open in new window


here is my code, TS-lint still failing with the error I mentioned.

 
 ngOnInit() {
    // lets  make a call and initialized the root object and children
    this.objectService.getObject().subscribe(root => {
      this.objectRoot = root;
      this.objectRoot.Object.Field.forEach(fi => {
        this.setUpObjectFieldData(fi);
        const filterArray = {};
        filterArray[fi.group] = filterArray[fi.group] || [];
        filterArray[fi.group].push(fi);
      });
    });

Open in new window

My first post had item.group and filteredArray = []
I then changed the filteredArray to an object. The second post was a sample to test the concept.

However, the problem is that you have not implemented the suggested code to match your data model.

Look at line 7 - you have that inside your loop - instead of outside of it look at where it is in my code on line 53

Next if your code is erroring - please post the error and the line number (Relative to your posted code) so I can see what is going on.

Finally, please dump your this.objectRoot.Object.Field property and paste here so I can see what your data looks like.
PS. I have not seen your full component code but remember to implement OnDestory and unsubscribe from the
this.objectService.getObject()

To do that you need to do the following
import { Component, OnInit, OnDestroy } from '@angular/core';
...
@Component({
  selector: 'component-selector',
  templateUrl: './template.component.html',
  styleUrls: ['./style.component.css']
})
export class YourComponent implements OnInit, OnDestroy {
private svcSub: ISubscription;
...
  ngOnInit() {
    this.svcSub = this.objectService.getObject().subscribe(root => {
      ...
    }
 }

  ngOnDestroy() {
    this.svcSub.unsubscribe();
  }
}

Open in new window

Avatar of Dev Me

ASKER


Look at line 7 - you have that inside your loop - instead of outside of it look at where it is in my code on line 53
This will be a logical issue. Ok put const outside of foreach loop.

below is TS-lint error I am talking about.
User generated image
Below is the sample for "fi" property that I am "consoling..."

{name: "Impact", $: "capability/functionality", group: "howbad"}
{name: "Info-req-on", $: "09/10/2003 03:00:00", group: "system"}
{name: "Integrated-releases", $: "002.005(026)", group: "version"}
{name: "Integrated-releases", $: "002.005(025)", group: "version"}

Open in new window


And finally thanks for your note on onDestroy(). I wasn't doing it.
Avatar of Dev Me

ASKER

on a side note...

seems like I can't directly "unsubscribe" from a service...meaning I can't do something like
 this.service.undersubscribe()

Open in new window


I have to assign subscribe call to a subscription and unsubscribe that subscription?

this.subscription = this.service.getObject().subscribe 

OnDesctroy()
{
 this.subscription.unsubscribe()
}

Open in new window


is that my understanding correct?
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Dev Me

ASKER

Ah...interesting...thanks for the solution. Changing  'String' to 'string' worked.  Never would have realized that.
Rule of thumb - stick to the basic types (lower case versions) - they are good for most instances.