0

I've got a couple views via ui-router and have a scope that I'm storing some input values in. The user can either enter information in one view and go to the next step or they can skip that step (and remove any entered data in the scope) and go to the next step.

I've tried many ways of trying to remove the element via $scope function and splice but I keep getting a TypeError - I know something is missing, but I can't seem to pinpoint it. I'd appreciate any help I can get!

Error:

TypeError: undefined is not a function
at Scope.$scope.remove (http://localhost:9000/scripts/app.js:27:32)
at http://localhost:9000/bower_components/angular/angular.js:10567:21
at http://localhost:9000/bower_components/angular/angular.js:18627:17
at Scope.$eval (http://localhost:9000/bower_components/angular/angular.js:12412:28)
at Scope.$apply (http://localhost:9000/bower_components/angular/angular.js:12510:23)
at HTMLButtonElement.<anonymous> (http://localhost:9000/bower_components/angular/angular.js:18626:21)
at http://localhost:9000/bower_components/angular/angular.js:2780:10
at forEach (http://localhost:9000/bower_components/angular/angular.js:330:20)
at HTMLButtonElement.eventHandler (http://localhost:9000/bower_components/angular/angular.js:2779:5) angular.js:9778
    (anonymous function) angular.js:9778
    (anonymous function) angular.js:7216
    Scope.$apply angular.js:12512
    (anonymous function) angular.js:18626
    (anonymous function) angular.js:2780
    forEach angular.js:330
    eventHandler angular.js:2779

Index.html

<!doctype html>
<html class="no-js">
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
</head>
<body ng-app="testappApp">

<!-- Add your site or application content here -->
<div class="container">
    <div ui-view></div>

</div>

<!-- build:js(.) scripts/oldieshim.js -->
<!--[if lt IE 9]>
<script src="bower_components/es5-shim/es5-shim.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
<![endif]-->
<!-- endbuild -->

<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/json3/lib/json3.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<!-- endbower -->
<!-- endbuild -->

    <!-- build:js({.tmp,app}) scripts/scripts.js -->
    <script src="scripts/app.js"></script>
    <script src="scripts/controllers/main.js"></script>
    <!-- endbuild -->
</body>
</html>

page1.html

<div class="jumbotron">
<h1>Page 1</h1>
<input type="text" ng-model="datas.veggie" placeholder="favorite veggie">
<a ui-sref="two">
Next
</a>
<button data-ng-click="remove(datas.veggie)">
Skip
</button>
<pre>
{{datas}}
</pre>
</div>

page2.html

<div class="jumbotron">
<h1>Page 2</h1>
<input type="text" ng-model="datas.color" placeholder="favorite color">
<a ui-sref="one">
Back
</a>
<button data-ng-click="remove(datas.color)">
Skip
</button>
<pre>
{{datas}}
</pre>
</div>

app.js

'use strict';

angular
  .module('testappApp', ['ui.router']).config(function($stateProvider, $urlRouterProvider){
    $stateProvider.state('one', {
        url: '/one',
        templateUrl: 'views/page1.html',
        controller: 'mainController'
    }).state('two', {
        url: '/two',
        templateUrl: 'views/page2.html'
    });
    $urlRouterProvider.otherwise('/one');
  }).controller('mainController', function($scope, $http) {

    $scope.datas = {'veggie':'none','color':'blue'};

    $scope.remove = function(whichone){
        var idx = $scope.datas.indexOf(whichone);
        $scope.datas.splice(idx,1);
    };

});
Jonas
  • 41
  • 1
  • 8

1 Answers1

1

$scope.datas is an object literal and therefore has no indexOf or splice methods.

If you would like to remove a property from your object by key you could use something like the following.

$scope.remove = function(key){
    if($scope.datas.hasOwnProperty(key)){
        delete $scope.datas[key];
    }
};
Jonathan Palumbo
  • 6,851
  • 1
  • 29
  • 40
  • The object literal not having `indexOf` or `splice` makes sense, thanks! However, `hasOwnProperty(key)` doesn't evaluate true or throw error. I tried ` – Jonas Aug 22 '14 at 19:59
  • `key` in your example needs to be a string value of `'veggie'` or `'color'` in order to return `true`, `delete` is not part of angular but rather a javacript keyword that removes a property from an object. If you would like to use `indexOf` and `splice` you will need to change your `$scope.datas` from an object to an array. – Jonathan Palumbo Aug 22 '14 at 20:03
  • That's perfect, thank you for bearing with my noobness. – Jonas Aug 22 '14 at 22:05