0

I am trying to get the user query from html using ng-click. I want to make a https call using the value which I fetch from ng-click. I can see the data in Alert--1 but in Alert--2 i get undefined. on internet I read that passing values using services is the best practice.Please correct me if I am wrong.

My controller

mainApp.controller('searchController',function($scope,searchString){

  $scope.getQuery = function(userq)  // its ng-click="getQuery(userq)" on Search button
  {
    $scope.userq=userq;
    alert('Alert--1'+userq);  // its working fine
    searchString.setSearchString(userq);
  };
});

//====================

mainApp.controller('fetchQueryResultController',function($scope,searchString){
   var searchStr = searchString.getSearchString();
   alert('Alert--2--'+searchStr);   //   Undefined
  // Later I'll use this value to fetch data from Watson search(Django) using $https call
});

My service:

mainApp.factory('searchString', function () {
    var qVal ;

    return {
        setSearchString:function (query) {
            qVal = query;
        },
        getSearchString:function () {
            return qVal;
        }
    };
});

Routing:

.when('/search', {
     templateUrl: "../static/views/seachResult.html",
     controller: "fetchQueryResultController"
  })

Is there any simpler way?

Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
  • please don't abandon posts to create new ones asking the [same question](http://stackoverflow.com/questions/33460627/pass-variable-inside-same-controller-from-ng-click-angular-js), you are getting mostly the same responses there as you were getting here. instead, choose one question and clarify your problem if you don't find the responses helpful enough. – Claies Nov 01 '15 at 14:03

3 Answers3

1

this alert undefined

var searchStr = searchString.getSearchString();
 alert('Alert--2'+searchStr);  

becuase qVal hasn't set yet

qVal set when getQuery get called but that time alert2 already executed

Anik Islam Abhi
  • 25,137
  • 8
  • 58
  • 80
1

Using a service is OK. Take a look at this, is quite clear for begginers:

https://egghead.io/lessons/angularjs-sharing-data-between-controllers

alert('Alert--2'+searchStr); is showing undefined because it is being executed before $scope.getQuery obviously. Controller's initialization is done before ng-init evaluates the expression.

In your case I believe it is better to fire an event when the data is set, so the second controller gets notified. This is being done with $on and $emit.

Here is a plunker with your example: http://plnkr.co/edit/97mVwbWmoOH3F7m8wbN0?p=preview

var app = angular.module('plunker', []);

app.controller('searchController',function($scope,searchString){

  $scope.searchText;

  $scope.getQuery = function(userq)  // its ng-click="getQuery(userq)" on Search button
  {
    $scope.userq=userq;
    alert('Alert--1'+userq);  // its working fine
    searchString.setSearchString(userq, $scope);
  };
});

//====================

app.controller('fetchQueryResultController',function($scope, $rootScope, searchString){
   var searchStr = searchString.getSearchString;

   $scope.getData = function(){
     searchStr = searchString.getSearchString();
     alert('Alert--2--'+ searchStr); 
   }

   $rootScope.$on('dataModified', function(){
     $scope.getData();
   });

});

//====================

app.factory('searchString', function ($rootScope) {
    var qVal ;

    return {
        setSearchString:function (query) {
            qVal = query;
            $rootScope.$emit('dataModified');
        },
        getSearchString:function () {
            return qVal;
        }
    };
});
Ignacio Villaverde
  • 1,264
  • 1
  • 11
  • 15
  • I have edited the code and have now created 2 controllers. One sets the user query and the other is called when view is rendered. I want to make my code woork, so made some changes as per the video, M i missing something? – Shashank Vivek Nov 01 '15 at 05:31
  • I have edited my answer for showing you a better solution, take a look at it! – Ignacio Villaverde Nov 01 '15 at 15:46
0

A simple solution is to have your factory return an object and let your controllers work with a reference to the same object:

JS:

// declare the app with no dependencies
var myApp = angular.module('myApp', []);


myApp.factory('searchString', function() {
  var qVal;

  return {
    setSearchString: function(query) {
      qVal = query;
    },
    getSearchString: function() {
      return qVal;
    }
  };
});

myApp.controller('setSearchController', function($scope, searchString) {
  $scope.setQuery = function(userq) {
    $scope.userq = userq;
    searchString.setSearchString(userq);
  };
});

myApp.controller('fetchQueryResultController', function($scope, searchString) {

  $scope.getQuery = function(user) {
    alert(searchString.getSearchString());
  };

});

HTML:

<div ng-app="myApp">
    <div ng-controller="setSearchController">
      <button ng-click="setQuery('Shohel')">Set</button>
    </div>
    <hr />
    <div ng-controller="fetchQueryResultController">
      <button ng-click="getQuery()">Get</button>
    </div>
  </div>

Here is similar fiddle

Shohel
  • 3,886
  • 4
  • 38
  • 75
  • Hi,m not able to figure out the way u want me to handle my existing routing code. I dont want to put ng-click. Its just that - why my service scope is not working outside `getQuery` ng-click function. I can use both **get** and **set** from service inside `getQuery` but not from outside. – Shashank Vivek Nov 01 '15 at 12:31
  • Please write plunker or fiddler that will help us for clear understanding – Shohel Nov 02 '15 at 01:53