0

I'm very new to Angular, and I'm really struggling to find a concise answer to this problem. I have a Form Component Here:

(I'm excluding the directives and imports as they're not really relevant)

export class JournalFormComponent implements OnInit {  

  public entries: EntriesService;  

  constructor(entries: EntriesService) { 
    this.entries = entries;
  }

  ngOnInit(): void {
  }

}

The EntriesService service just stores an array of entries:

export class Entry {
  constructor (
    public num: number,
    public name: string,
    public description: string,
    public text: string
  )  { }  
}

The Form Component template renders a <h2> and a <app-input> Component for each entry in the EntriesService, which works. That looks like this:

<div *ngFor="let entry of entries.entries">
  <h2> {{ entry.num }}. {{ entry.name }} </h2>
  <app-input id="{{entry.num}}"></app-input>
</div>

Here's the <app-input> Input Component:

@Component({
  selector: 'app-input',
  template: `
    <textarea #box
      (keyup.enter)="update(box.value)"
      (blur)="update(box.value)">
    </textarea>
    `
})
export class InputComponent {
  private value = '';    

  update(value: string) { 
    this.value = value;    
  }

  getValue () {
    return this.value;
  }  
}

The InputComponent stores the user's text perfectly, but I don't know how to pass that data to the Form Component's EntriesService to update the Entry in order to Export it or Save it later. How is this done?

I think I'm phrasing this question well, but I'm not sure. If you need clarification I'll provide it.

Not sure if it matters, but I'm using Angular 9.1.11

3
  • The Angular docs are your best source of information for inter-component communication. Specifically: angular.io/guide/… Commented Aug 17, 2020 at 1:58
  • just set the form data to a new variable in the service: this.entries.savedData = this.value and use it later. Commented Aug 17, 2020 at 3:17
  • You can use @Output event emitter here when save the value from InputComponent call event emitter to the JournalFormComponent angular.io/guide/inputs-outputs Commented Aug 17, 2020 at 4:40

2 Answers 2

1

There are many ways to update the data from one component to another.

  1. component to component using service or subjects
  2. parent~child component data exchange using Input() and Output() decorators. Or by using @ViweChild() interactions. and many more

But please do check the angular docs https://angular.io/guide/component-interaction .

Use the below simple code, u might need to include modules like FormsModule. and import Input(), Output etc

@Component({
  selector: 'app-journal-form',
  template: `
    <div *ngFor="let entry of entries.entries; let i=index">
      <h2> {{ entry.num }}. {{ entry.name }} </h2>
      <app-input id="{{entry.num}}" [entry]="entry" [arrayIndex]="i" (updateEntry)="updateEntry($event)" ></app-input>

    </div>`
})
export class JournalFormComponent implements OnInit {
  constructor(private entries: EntriesService) { 
    this.entries = entries;
  }

  ngOnInit(): void {
  }

  updateEntry(event){
    console.log(event);
    this.entries[event.arrayIndex] = event.entry;
  }

}
@Component({
  selector: 'app-input',
  template: `
    <textarea [(ngModel)]="name"
      (keyup.enter)="update()"
      (blur)="update()">
    </textarea>
    `
})
export class InputComponent {
  @Input() entry: any;
  @Input() arrayIndex: number;
  @Output() updateEntry: EventEmitter<any> = new EventEmitter();
  name:string;
  constructor() { 
    console.log(entry);
    this.name = entry.name;
  }

  update(){
    this.entry.name = this.name;
    this.updateEntry.emit({entry: this.entry, arrayIndex});
  }

}
Sign up to request clarification or add additional context in comments.

1 Comment

I have seen Output() in other places, but I never saw Input() with a template. This did the trick.
0

Output event will help in this situation.

<div *ngFor="let entry of entries.entries">
  <h2> {{ entry.num }}. {{ entry.name }} </h2>
  <app-input id="{{entry.num}}" (entryChange) = "entry.text = $event"></app-input>
</div>

app-input component

export class InputComponent {
  private value = '';
  @Output() entryChange = new EventEmitter<string>();
  update(value: string) { 
    this.value = value;
   this.entryChange.emit(value);
  }
}

Instead of entry.text = $event you can also pass it to any save function, like saveEntry($event);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.