Error: [$resource:badcfg] , how can I fix that? - json

I'm just getting my first steps with angular and stuff, here's my service:
(function() {
'use strict';
angular
.module('timeTracker')
.factory('time', time);
function time($resource) {
// ngResource call to our static data
var Time = $resource('data/time.json');
function getTime() {
// $promise.then allows us to intercept the results
// which we will use later
return Time.query().$promise.then(function(results) {
return results;
}, function(error) { // Check for errors
console.log(error);
});
}
return {
getTime: getTime,
}
}
The 'data/time.json' is pre-filled, I don't have a back-end system yet.
And here's my controller:
(function() {
'use strict';
angular
.module('timeTracker')
.controller('TimeEntry', TimeEntry);
function TimeEntry(time) {
// vm is our capture variable
var vm = this;
vm.timeentries = [];
// Fetches the time entries from the static JSON file
// and puts the results on the vm.timeentries array
time.getTime().then(function(results) {
vm.timeentries = results;
console.log(vm.timeentries);
}, function(error) { // Check for errors
console.log(error);
});
}
})();
So far I've just tried to wire all together in a index.html file, but something keeps going wrong.
My index's body looks like this:
<body ng-app="timeTracker" ng-controller="TimeEntry as vm">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Time Tracker</a>
</div>
</div>
<div class="container-fluid time-entry">
<div class="timepicker">
<span class="timepicker-title label label-primary">Clock In</span>
<timepicker ng-model="vm.clockIn" hour-step="1" minute-step="1" show-meridian="true">
</timepicker>
</div>
<div class="timepicker">
<span class="timepicker-title label label-primary">Clock Out</span>
<timepicker ng-model="vm.clockOut" hour-step="1" minute-step="1" show-meridian="true">
</timepicker>
</div>
<div class="time-entry-comment">
<form class="navbar-form">
<input class="form-control" ng-model="vm.comment" placeholder="Enter a comment">
</input>
<button class="btn btn-primary" ng-click="vm.logNewTime()">Log Time</button>
</form>
</div>
</div>
</nav>
<div class="container">
<div class="col-sm-8">
<div class="well timeentry" ng-repeat="time in vm.timeentries">
<div class="row">
<div class="col-sm-8">
<h4><i class="glyphicon glyphicon-user"></i>
{{time.user_firstname}} {{time.user_lastname}}</h4>
<p><i class="glyphicon glyphicon-pencil"></i> {{time.comment}}</p>
</div>
<div class="col-sm-4 time-numbers">
<h4><i class="glyphicon glyphicon-calendar"></i>
{{time.end_time | date:'mediumDate'}}</h4>
</div>
</div>
</div>
</div>
</div>
</body>
Anyway, I couldn't figure out a way to make this work so far. I keep getting the same error in the console log :
[Error] Error: [$resource:badcfg] Error in resource configuration for action `query`. Expected response to contain an array but got an object
http://errors.angularjs.org/1.3.15/$resource/badcfg?p0=query&p1=array&p2=object
http://localhost/TimeTracker/bower_components/angular/angular.js:63:32
http://localhost/TimeTracker/bower_components/angular-resource/angular-resource.js:587:40
processQueue#http://localhost/TimeTracker/bower_components/angular/angular.js:13248:29
http://localhost/TimeTracker/bower_components/angular/angular.js:13264:39
$eval#http://localhost/TimeTracker/bower_components/angular/angular.js:14466:28
$digest#http://localhost/TimeTracker/bower_components/angular/angular.js:14282:36
$apply#http://localhost/TimeTracker/bower_components/angular/angular.js:14571:31
done#http://localhost/TimeTracker/bower_components/angular/angular.js:9698:53
completeRequest#http://localhost/TimeTracker/bower_components/angular/angular.js:9888:15
requestLoaded#http://localhost/TimeTracker/bower_components/angular/angular.js:9829:24
(anonymous function) (angular.js, line 11655)
(anonymous function) (angular.js, line 8596)
processQueue (angular.js, line 13256)
(anonymous function) (angular.js, line 13264)
$eval (angular.js, line 14466)
$digest (angular.js, line 14282)
$apply (angular.js, line 14571)
done (angular.js, line 9698)
completeRequest (angular.js, line 9888)
requestLoaded (angular.js, line 9829)
So, splitting out the index's body, everything works just fine within the <nav> tag, but not a single dot comes out from the "container".

In your code, you forgot a few lines
(function() {
'use strict';
angular
.module('timeTracker')
.factory('time', time);
function time($resource) {
// ngResource call to our static data
var Time = $resource('data/time.json');
function getTime() {
// $promise.then allows us to intercept the results
// which we will use later
return Time.query().$promise.then(function(results) {
return results;
}, function(error) { // Check for errors
console.log(error);
});
}
return {
getTime: getTime,
}
}
Is missing the lines below:
})();
Working code:
http://embed.plnkr.co/RSIBLVHB8HZ03xPAa0nZ

'use strict'; doesn't allow implicit dependency declaration. Try
angular
.module('timeTracker')
.factory('time', ['$rosource', time]);
and
angular
.module('timeTracker')
.controller('TimeEntry', ['time', TimeEntry]);
or remove the 'use strict';

Related

TypeScript Angular: Can you have an (click) event with an object property as its value?

I am trying to create a dynamic error card, with different error messages and with a retry button.
Here is a snippet of my typescript object:
errorCard: any = [];
if(error){
this.errorCard.errorMessage = "oops try again"
this.errorCard.buttonFunc = "retry()";
}
Now this is my view:
<div class="card-block">
<div class="card-media-block wrap">
<div class="card-body">
<span class="card-media-title">
{{errorCard.errorMessage}} // works as expected
</span>
...
<div class="card-footer">
//this click is where I would like it to call the function that is tied to that property in this case retry()
<button (click)="errorCard.buttonFunc"><i class="fas fa-redo-alt"></i> Retry</button>
</div>
I do not receive any errors in the console with this, and the function does not get triggered.
I thank you guys in advance for your help!
Assuming that your Component is something like this:
import { Component } from '#angular/core';
#Component({...})
export class YourComponent {
errorCard = {};
...
retry() {
console.log('Retry Got Called');
}
}
Why don't you simply call the retry method like this(<button (click)="retry()">Retry</button>):
<div class="card-block">
<div class="card-media-block wrap">
<div class="card-body">
<span class="card-media-title">
{{errorCard.errorMessage}} // works as expected
</span>
...
<div class="card-footer">
//this click is where I would like it to call the function that is tied to that property in this case retry()
<button (click)="retry()"><i class="fas fa-redo-alt"></i> Retry</button>
</div>
</div>
</div>
</div>
Give this Working Sample StackBlitz a try.

How to change ng-include inside firebase firestore function

When I click on continue button it checks clients ID in firestore database and if ID does'nt exist then $scope.filePath = "createClient.htm" is called. everything is working fine but when I call this piece of code inside firebase function nothing happens
Inside HTML
<div ng-include="filePath" class="ng-scope">
<div class="offset-1 offset-sm-2 col-11 col-sm-7">
<h2>Enter Client ID</h2>
<br>
<div class="form-group">
<label for="exampleInputEmail1">ID</label>
<input id="client_id" type="text" class="form-control" placeholder="Client ID">
</div>
<div class="float-right">
<button type="button" class="btn btn-danger">Cancel</button>
<button type="button" ng-click="searchClient()" class="btn btn-success">Continue</button>
</div>
</div>
</div>
Internal Script
<script>
$scope.searchClient = function()
{
//$scope.filePath = "createClient.htm"; it works here
var id= document.getElementById('client_id').value;
db.collection("clients") // db is firestore reference
.where("c_id","==",id)
.get()
.then(function(querySnapshot)
{
querySnapshot.forEach(function(doc)
{
if(!doc.exists)
{
console.log("Client Does'nt Exist");
$scope.filePath = "createClient.htm"; // but doesnt works here inside this firebase function
}
}
);
}
);
}
};
</script>
when console.log is shown and firebase function are fully executed then if I click on "Continue" Button again it works fine and content of createClient.htm is shown inside ng-include="filePath". why i need to click twice ?

type error : Cannot read value 'name' of undefined

I'm working with Angularjs and firebase to create an app that is a task timer. I create the firebase object and all works fine except when I try to log task.newTask to the console. Here's a bit of my code (please note this is not all the code):
//HTML
<aside id="sidebar">
<section id="widget_1">
<h2 class="titles">Task History:</h2>
<input id="text-field" type="text" ng-model="taskText" />
<input id="task-button" type="button" value="Add Task" ng-click="addTask()" />
</section>
<section id="widget_2">
<h2 class="titles">Task List:</h2>
<table>
<tr ng-repeat="task in timer_tasks | orderBy: '-taskText'">
<td>{{ task.taskText }}</td>
</tr>
</table>
</section>
</aside>
//Controller:
(function() {
'use strict'
function HomeCtrl($scope, $firebaseArray, $interval) {
console.log('I see you home controller ... you are loaded sir!!!')
var timerRef = firebase.database().ref().child('timer_tasks');
$scope.timer_tasks = $firebaseArray(timerRef);
$scope.addTask = function () {
$scope.timer_tasks.$add({
taskText: $scope.taskText,
newTask: true
}).then(function (timerRef) {
$scope.taskText = '';
});
};
console.log(task.newTask);
On page load the error comes up at console.log(task.newTask);
Any help would be great. Thanks in advance!
If i'm understood correctly, you need to retrieve textbook value in controller which will build $scope.timer_tasks and later can be retrieved back to view in ng-repeat.
view
<aside id="sidebar">
<section id="widget_1">
<h4 class="titles">Task History:</h4>
<input id="text-field" type="text" ng-model="taskText" />
<input id="task-button"
type="button"
value="Add Task"
ng-click="addTask(taskText)"/>
</section>
</aside>
Script
myApp.controller('myCtrl', function($scope) {
$scope.addTask = function (value) {
console.log(" clicked : "+value);
};
});
All i did was bind the value upon addTask click from ng-model to ng-click and as you can see now you have that value in addTask function.

Angular Js get Json not working

I'm trying to make a simple angular app which reads json data , but in response I'm only getting "," not data.Any pointers where I m going wrong ? I have attached index.html and abc.json file that i m keepingat server
PFB the code .
HTML:
<body ng-app="sampleApp" ng-controller="ctrl1">
Name:<input type="text" ng-model="name">
<ul>
<li ng-repeat="student in students | filter:name">{{student.name +","+student.empNo}</li>
</ul>
Name:<input type="text" ng-model="newname">
EmpNo:<input type="text" ng-model="newemp">
<input type="button" value="AddMe" ng-click="add()"/>
<div>
<div ng-view></div>
</div>
Javascript:
var x=angular.module('sampleApp',[])
.factory("simpleFactory",function($http){
var factory={};
factory.getStudents=function(){
return $http.get("abc.json");
}
return factory;
})
.controller("ctrl1",function($scope,simpleFactory){
$scope.students=simpleFactory.getStudents();
$scope.add=function(){
$scope.students.push(
{
name:$scope.newname,empNo:$scope.newemp
}
)
}
})
abc.json
[
{"name":"jack","empNo":"1"},
{"name":"Red","empNo":"2"},
{"name":"Jill","empNo":"3"}
]
getStudents is asynchronous. You should retrieve and assign students through the callback handler.
.factory("simpleFactory",function($http){
var factory={};
factory.getStudents = $http.get("abc.json");
return factory;
})
.controller("ctrl1",function($scope,simpleFactory){
simpleFactory.getStudents().then(function(result) {
$scope.students= result.data;
});
...
})
Nearly right. getStudents in fact returns you a 'Promise', not the data itself. You have to use that Promise to get your data:
simpleFactory.getStudents().then(function(data) {
$scope.students=data
// $scope.students=data.data // you may need this given your feedback
});

How do I update the model on click only (angular-strap typeahead and json)

I'm having trouble figuring out how to have dynamic data only update when the user selects from the typeahead menu or clicks the search button.
Right now, the dynamic content pertaining to the search query updates automatically when the input value is changed (content disappears). I want the content to stay in view until a new selection has been either clicked in the typeahead list or clicked by the search button.
Any insight at all would be greatly appreciated! Thank you!
Plunker demo:
http://plnkr.co/edit/jVmHwIwJ0KOKCnX6QjVa?p=preview
Code:
<!-- HTML -->
<body ng-controller="MainController">
<!-- Search -->
<div class="well">
<p>Search the term "content"</p>
<form role="form">
<div class="form-group clearfix search">
<input type="text" ng-model="selectedContent" ng-options="query as query.searchQuery for query in searchData" bs-typeahead="bs-typeahead" class="form-control search-field"/>
<button type="button" class="btn btn-primary search-btn"><span class="glyphicon glyphicon-search"></span></button>
</div>
</form>
</div>
<!-- Dynamic Content -->
<div class="well">
<h4>{{ selectedContent.contentTitle }}</h4>
<ul>
<li ng-repeat="item in selectedContent.headlines">{{item.headline}}</li>
</ul>
</div>
<!-- typeahead template -->
<ul class="typeahead dropdown-menu" tabindex="-1" ng-show="$isVisible()" role="select">
<li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}">
</li>
<!-- JS -->
var app = angular.module('demoApp', ['ngAnimate', 'ngSanitize', 'mgcrea.ngStrap'])
.config(function ($typeaheadProvider) {
angular.extend($typeaheadProvider.defaults, {
template: 'ngstrapTypeahead.html',
container: 'body'
});
});
function MainController($scope, $templateCache, $http) {
$scope.selectedContent = '';
$http.get('searchData.json').then(function(response){
$scope.searchData = response.data;
return $scope.searchData;
});
};
You could use a directive such as this:
app.directive('mySearch', function(){
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, $element, $attrs, ngModel){
ngModel.$render = function(){
if (angular.isObject($scope.selectedContent)) {
$scope.clickedContent = $scope.selectedContent;
}
}
$scope.updateModel = function() {
$scope.clickedContent = $scope.selectedContent;
}
}
}
})
plunker
Edit:
I added using the ngModelController. The function you set ngModel.$render to gets called whenever the model updates. If you click the typahead popup, then the model selectedContent will be an object, otherwise it'll be a string. If it's an object (meaning the user clicked the typahead popup) we do the same as we did in the updateModel function.