Showing posts with label AngularJs. Show all posts
Showing posts with label AngularJs. Show all posts

Tuesday, August 13, 2019

ReactJs - Convert JSON Data using loadash

Hello,

Finally now I am going to post few blogs on React and ReactJs. In this blog we are going to learn how we can modify, manipulate or edit JSON data received from API according to your need.

This will be very useful when your backend developer refused to change API response. So not to worry, let it be as it is and convert data on your side before you use it.

For this we are going to use Lodash library, so first of all add it your ReactJs project using npm and import it in your class file.

import _ from "lodash";

Now create function for converting data.

const convertData = (data, key) =>{
  let result = _.chain(data)
    .get(key)
    .map(d => ({
      modified_key1: _.get(d, "original_key1"),
      modified_key2: _.get(d, "original_key2"),
      modified_key3: _.get(d, "original_key3"),
      modified_key4: _.get(d, "original_key4")
    }))
    .value();
    return result;
}

Now call this function in your API response.

let modifiedData = convertData(response.body, "data");

Here data is the root key of your JSON response. Change it according to your JSON response. That's it now you have modified data according to your requirements.

Sunday, December 10, 2017

AngularJs - Get Controller Scope in Directive

Recently I was learning AngularJs 5 and where I faced problem. I have to call controller function from directive. After struggle of half an hour, I was able to solve it. In this blog I am going to explain how to do this.

First of all give id to HTML tag where you have added ng-controller directive.

<div ng-controller="MyController" id="myControllerDiv">
</div>

Now in directive or any external JavaScript code where you want to get contoller scope, use following code.

var element  = document.getElementById("myControllerDiv");

This will give us that element, we will find it's corresponding angular element.

var angularElement  = angular.element(element);

Now we will get it's scope and using that scope, we can all any function of MyController

angularElement.scope().myFunction()

This will call myFunction defined in MyController.

Hope this helps you.

Monday, June 23, 2014

How to Access $scope Variable Outside AngularJs Controller

Recently I was working with AngularJs and there was a requirement to call a AngularJs controller function forcefully from other events.  So for that we have to access $scope variable of a controller. This short blog is about accessing $scope variable.

In AngularJs all the scopes are bound to DOM so to access $scope first we have to get the HTML element. You can either use jQuery selectors to get elements or you can use standard document.getElementById method. For example.

var scope= angular.element($(".classselector")[0]).scope();

This gives you the scope of the the element. Once you have the scope you can call respective method of controller.  There is also other way to find out the scope if you don't have reference to element. You can find scope by name of controller.

var scope = angular.element($('[ng-controller=myController]')).scope();

After you make changes to variables of scope you have to call apply method so the AngularJs framework is notified about changes.

scope.$apply();

Hope this helps you.


Saturday, June 21, 2014

AngularJs Communicate Between Directives and Controllers

Hello,

Recently in one of my project we were using AngularJs and created a directive for timepicker where user can enter timer in hh:mm AM/PM format. Now on one of the HTML form we have a button. When the button is clicked we have to disable the input for the timepicker. For that we have to access scope of directive from scope of AngularJs controller so that se can disable the respective field. In this blog I am going to explain how to do this.

AngularJs allows you to create directives with isolated scope which has some binding to parent scope. Bindings are defined by specifying attributes in HTML.  In some cases it may not be good as it's hard to synchronize both the scopes. So ideally parent and directive scope should be maintained separately. Better way to communicate between directives and controllers is through directive attributes. Let's see and example.  I have defined my HTML as follow for my timepicker directive.

<timepicker is-not-open="notOpen" hour-step="1" minute-step="30" show-meridian="true"></timepicker>

As you can see above is-not-open is the attribute defined for directive and it is bind to notOpen variable in my controller.

$scope.notOpen = false;

Now lets see how to mention attribute in directive scope.

angular.module('ui.bootstrap.timepicker', [])
.directive('timepicker', ['timepickerConfig', function (timepickerConfig) {
  return {
    restrict: 'EA',
    require:'?^ngModel',
    replace: true,
    scope: { isNotOpen: "=" },
    templateUrl: 'template/timepicker/timepicker.html',
    link: function(scope, element, attrs, ngModel) {
     
    }
  };
}]);

As you can see in above code we have defined attribute with scope: { isNotOpen: "=" }. Now you can define a function to watch this variable in directives. For example there is a method in parent controller which sets notOpen variable to true.

$scope.setNotOpenStatus = function(){
      $scope.notOpen = true;
}

Once it is set here, the directive is notified about the change and as I mentioned you can keep watch on the attribute.

scope.$watch('isNotOpen', function (newValue, oldValue) {
          if(newValue == true){
              //do something
          }
});

Same way you can have watch function in parent controller which would be notified if attribute value is changed inside directive.

Hope this helps you.

Wednesday, May 28, 2014

AngularJs and $scope.$apply - When and How to use $apply for AngularJs scope

In this blog I will explain when to use $apply for AngularJs $scope and how to use it. You may have encountered the situation where you update the variables bind to AngularJs view but it does not update views. So here I will explain why it happens and how to resolve it. Also you need to know how to use $apply carefully else it may give you error that $apply is already in progress.

First lets understand how the AngularJs data binding works.AngularJs framework monitors data changes with the digest cycles. That means it checks it frequently in digest cycle then framework will be notified if you have made any changes in managed code. But there are chances that you have some external events like Ajax callbacks or some native click events. These event runs outside the scope of AngularJs digest cycles. So the framework does not know about any changes made during this events. You have to tell the framework that there are changes. Here $apply comes to the picture. It lets you start digest cycle explicitly. So that your frameworks knows that there are changes. Lets assume that you have variable $scope.myVar and you changed its value in native click event. So you need to tell Framework that it is changed. So if you simply use,

$scope.myVar = 'New Value';

It will not work. Instead of this you have to use

$scope.$apply(function(){
      $scope.myVar = 'New Value';
});

or you can use this syntax.

$scope.myVar = 'New Value';
$scope.$apply();


This shall notify the framework that the value is changed. It's not always safe to use $apply as I mentioned earlier. If the digest cycle is already in progress and you try to set it and with $apply it will give you an error. So if you have condition like your variable is updated at common function which you calls from AngularJs managed code and outside events. you have to first check it digest cycle is already in progress. If not then only use $apply. You can check it with following code.

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
       $scope.myVar = 'New Value';
       $scope.$apply();
}

This will be the safe apply and it will not give you any error .


Thursday, May 22, 2014

Add Buttons on Headings of AngularJs BootstrapAccordion

Recently in one of my projects we were using AngularJs and Bootstrap UI. We have a layouts where we have buttons on heading of accordion and we have to add click events for it.



So we know the behavior of accordion. When we click on headings of accordion it actually expands it. In My case I have to stop and that and invoke button click function. In this blog I will explain this.

Basic idea is to stop event propagation. So when we click on button it will invoke handler for it and and if we stop propagation of event in that function it will not expand the accordion view. Lets assume we have following delete button on accordion heading.

So when I click on delete it should actually remove that record instead of opening the accordion. For that add click handler for the buttons as follow.

<accordion-heading>
     <div>
          Options
     </div>
     <div style="float:right">
          <button ng-click="deleteItem(item, $event)" type="button" class="btn" style="color: #000"               >Delete</button>
     </div>
</accordion-heading>

As you can see in above code we have added click event handle with ng-click and we are passing item and event as parameter. Now in controller add the event handler.

$scope.deleteItem = function(item, $event){
      $event.stopPropoagation();
}

As you can see in above code we are using stopPropagation method of event object to stop event propagation. Hence the event does not propagated and accordion will not expand. If you click anywhere else it will open it but if you click on delete button it will not invoke it. Hope this helps you.

Saturday, April 26, 2014

AngularJs Pass Data Between Controllers

Hello,

This is my first blog on AngularJs. I have been working with AngularJs since last three or four weeks and I am very excited about this Framework. It has nice features like two way data binding, templates, MVVM model, directives. That makes this framework super cool. I will be adding more blogs in future for AngularJs. In this blog I will explain how to pass data between controllers.

For this first we have to understand $rootScope. Every AngularJs application has one root scope and all other scopes are children of root scope. It's like application wide global variable.

Now lets see how we can use this to share data between controllers. First we need a service which is common in both controllers. We will invoke a service function from a controller which wants to send data. Service will broadcast it and using $rootScope. While the receiver controller will listen to the broadcast event and receives that data. First lets crete a service and function.

var servicesModule = angular.module('myapp.broadcastservice', []);

servicesModule.factory('BroadcastService', ['$http', '$rootScope', function ($http, $rootScope) {

   var service = {};
   service.sendData = function(data){

      $rootScope.$broadcast('message', data);
   }

}

Now lets create sender controller.

appRoot.controller('SenderController', ['$scope', 'BroadcastService',
   function ($scope, BroadcastService) {
        $scope.sendData = function(){
              BroadcastService.sendData("My Message");
        }
   }
]);

Now lets create a receiver controller

appRoot.controller('ReceiverController', ['$scope', 'BroadcastService',
    function ($scope, BroadcastService) {
        $scope.$on('message', function(response, data) {
            console.log(data);
       });
    }
]);

As you can see from sender controller we invoke service function and broadcast message with event message and in receiver controller we receive it by listening to message event using $scope.$on.

This way you can pass data between AngularJs controllers. Hope this post helps you.