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);
    };

});

1 Answer 1

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];
    }
};
Sign up to request clarification or add additional context in comments.

3 Comments

The object literal not having indexOf or splice makes sense, thanks! However, hasOwnProperty(key) doesn't evaluate true or throw error. I tried <button data-ng-click="remove(veggie)"> and <button data-ng-click="remove(datas.veggie)">. I didn't see anything about angular delete, only splice method to delete from the array and that's why I'd been trying it like that: link
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.
That's perfect, thank you for bearing with my noobness.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.