0

I'm struggling with a problem within Angular v1.6.1 where I am trying to transfer some data from a component to another component.


I have a component called navbar which resides in app\common\navbar has a controller that fetches data from a service. The following files make up navbar component

navbar.component.js

import controller from './navbar.controller';
import template from './navbar.html';
export default navbarComponent = {
  restrict: 'E',
  bindings: {},
  template,
  controller
};

navbar.controller.js

class NavbarController {
  constructor(httpService) {
    const dataUrl = "/assets/data/header.json";
    this.name = 'Navbar';
    this.headerData = {};
    console.log("In "+this.name);
    httpService.getData(dataUrl)
      .then((response) => {
          angular.extend(this.headerData,response.data);
      },(error) => { throw error; });
  }
}
export default NavbarController;

navbar.html

<section>
  <top-header top-data="$ctrl.headerData"></top-header>
<section>

and my httpService resides in app\services folder. It fetches content using axios http library and looks something like this

httpService.js

import axios from 'axios';
export class HttpService {
    constructor() {
        this.name = "HttpService";
    }
    getData(api_url){
      return axios.get(api_url)
        .then((response) => response, (error) => error);
    }
}

The component which uses my navbar component's headerData is top-header and resides in app\common\top-header. This is what it contains

top-header.component.js

import template from './top-header.html';
import controller from './top-header.controller';

export default topHeaderComponent = {
  restrict: 'E',
  template,
  bindings: {
      topData: '<'
  },
  controller,
};

top-header.controller.js

class TopHeaderController {
  constructor() {
    this.name = 'TopHeader';
    this.topHeaderData = {};
    this.$onInit = function() {
       this.topHeaderData = this.topData;
       console.log(this.topHeaderData);
       console.log(this.topHeaderData.telephoneNumber);
       console.log(this.topHeaderData);
    }
  }
}
export default TopHeaderController;

top-header.html

{{$ctrl.topHeaderData.telephoneNumber}}

and finally my static files resides in assets\data and the JSON I'm trying to fetch header.json contains

header.json

{
    "telephoneNumber": 12345678
}

So the problem now I see is that the data does show up in my top-header component but I'm not sure what's happening but the data disappears (comes up undefined) once I try to access the object property.

What I'm saying is that in top-header.controller.js when I console.log(this.topHeaderData); it shows the object but when I try to console.log(this.topHeaderData.telephoneNumber); it comes up undefined

I think the problem exists because of the execution priority of the Directives. I even set navbar component priority to 5 and it didn't help as the data is undefined.

top-header.controller.js

this.$onInit = function() {
   this.topHeaderData = this.topData;
   console.log(this.topHeaderData); // shows topData
   console.log(this.topHeaderData.telephoneNumber);  // undefined
   console.log(this.topHeaderData); // shows topData
}

This data this.topHeaderData.telephoneNumber is essential as I use this in my template.

How can I resolve this issue? Any help would be greatly appreciated.

rand0m
  • 842
  • 10
  • 24

1 Answers1

0

The problem may be in top-header.controller.js: you're assigning binded topData to this.topheaderData in $onInit hook but when component is initialized the data hasn't been fetched yet. Instead of $onInit you should use $onChange hook method which is called by Angular when binded property is updated (in your case when data is fetched from server)

Angular component docs:

$onChanges(changesObj) - Called whenever one-way bindings are updated. The changesObj is a hash whose keys are the names of the bound properties that have changed, and the values are an object of the form { currentValue, previousValue, isFirstChange() }. Use this hook to trigger updates within a component such as cloning the bound value to prevent accidental mutation of the outer value.

Bartek Fryzowicz
  • 6,464
  • 18
  • 27