Erro: 404 Bad request Mongo, Express, Angular, Node - angularjs

I have a problem I can not solve, my application is returning the error 400 bad request, where I can not do any post, but using the postman it works normally I can do get, post, put, delete, but in my application does not Make it possible to do the post, I have done and redid the code several times and the problem is not remedied, I need to solve this
My Controller
angular.module('primeiraApp').controller('CarCycleCtrl', [
'$scope',
'$http',
'$location',
'msgs',
'tabs',
'consts',
CarCycleController
])
function CarCycleController($scope, $http, $location, msgs, tabs, consts) {
$scope.getCarCycles = function() {
const page = parseInt($location.search().page) || 1
const url = `${consts.apiUrl}/carCycles?skip=${(page - 1) * 10}&limit=10`
$http.get(url).then(function(resp) {
$scope.carCycles = resp.data
$scope.carCycle = {}
initCarsAndOuts()
$http.get(`${consts.apiUrl}/carCycles/count`).then(function(resp) {
$scope.pages = Math.ceil(resp.data.value / 10)
tabs.show($scope, {tabList: true, tabCreate: true})
})
})
}
$scope.createCarCycle = function(){
const url = `${consts.apiUrl}/carCycles`;
$http.post(url,$scope.carCycle).then(function(response){
$scope.carCycle = {}
initCarsAndOuts()
$scope.getCarCycles()
msgs.addSuccess('Operação realizada com sucesso!')
}).catch(function(resp){
msgs.addError(resp.data.errors)
})
}
$scope.showTabUpdate = function(carCycle) {
$scope.carCycle = carCycle
initCarsAndOuts()
tabs.show($scope, {tabUpdate: true})
}
$scope.updateCarCycle = function() {
const url = `${consts.apiUrl}/carCycles/${$scope.carCycle._id}`
$http.put(url, $scope.carCycle).then(function(response) {
$scope.carCycle = {}
initCarsAndOuts()
$scope.getCarCycles()
tabs.show($scope, {tabList: true, tabCreate: true})
msgs.addSuccess('Operação realizada com sucesso!')
}).catch(function(resp) {
msgs.addError(resp.data.errors)
})
}
$scope.showTabDelete = function(carCycle) {
$scope.carCycle = carCycle
initCarsAndOuts()
tabs.show($scope, {tabDelete: true})
}
$scope.deleteCarCycle = function() {
const url = `${consts.apiUrl}/carCycles/${$scope.carCycle._id}`
$http.delete(url, $scope.carCycle).then(function(response) {
$scope.carCycle = {}
initCarsAndOuts()
$scope.getCarCycles()
tabs.show($scope, {tabList: true, tabCreate: true})
msgs.addSuccess('Operação realizada com sucesso!')
}).catch(function(resp) {
msgs.addError(resp.data)
})
}
$scope.addDebt = function(index) {
$scope.carCycle.outs.splice(index + 1, 0, {})
}
$scope.cloneDebt = function(index, {name, value, status}) {
$scope.carCycle.outs.splice(index + 1, 0, {name, value, status})
initCarsAndOuts()
}
$scope.deleteDebt = function(index) {
$scope.carCycle.outs.splice(index, 1)
initCarsAndOuts()
}
$scope.addCredit = function(index) {
$scope.carCycle.cars.splice(index + 1, 0, {name: null, value: null})
}
$scope.cloneCredit = function(index, {name, value}) {
$scope.carCycle.cars.splice(index + 1, 0, {name, value})
initCarsAndOuts()
}
$scope.deleteCredit = function(index) {
$scope.carCycle.cars.splice(index, 1)
initCarsAndOuts()
}
$scope.cancel = function() {
tabs.show($scope, {tabList: true, tabCreate: true})
$scope.carCycle = {}
initCarsAndOuts()
}
$scope.calculateValues = function() {
$scope.car = 0
$scope.out = 0
if($scope.carCycle) {
$scope.carCycle.cars.forEach(function({value}) {
$scope.car += !value || isNaN(value) ? 0 : parseFloat(value)
})
$scope.carCycle.outs.forEach(function({value}) {
$scope.out += !value || isNaN(value) ? 0 : parseFloat(value)
})
}
$scope.total = $scope.car - $scope.out
}
var initCarsAndOuts = function() {
if(!$scope.carCycle.outs || !$scope.carCycle.outs.length) {
$scope.carCycle.outs = []
$scope.carCycle.outs.push({})
}
if(!$scope.carCycle.cars || !$scope.carCycle.cars.length) {
$scope.carCycle.cars = []
$scope.carCycle.cars.push({})
}
$scope.calculateValues()
}
$scope.getCarCycles()
}
My Backend
const _ = require('lodash')
const CarCycle = require('./carCycle')
CarCycle.methods(['get', 'post', 'put', 'delete'])
CarCycle.updateOptions({new: true, runValidators: true})
CarCycle.after('post', sendErrorsOrNext).after('put', sendErrorsOrNext)
function sendErrorsOrNext(err, req, res, next) {
const bundle = res.locals.bundle
if(bundle.errors) {
var errors = parseErrors(bundle.errors)
res.status(500).json({errors})
} else {
next()
}
}
function parseErrors(nodeRestfulErrors) {
const errors = []
_.forIn(nodeRestfulErrors, error => errors.push(error.message))
return errors
}
CarCycle.route('count', function(req, res, next) {
CarCycle.count(function(error, value) {
if(error) {
res.status(500).json({errors: [error]})
} else {
res.json({value})
}
})
})
module.exports = CarCycle

Related

Memory leak warnings in electron

I'm getting memory leak warning in the console for my Electron app, i don't know what to do to increase limit. It's causing it everytime i run the app.
Does the error is linked to uiohook? Or did i miss something here?
How can i use emitter.setMaxListeners() in my case? I have no clue of how to fix it, and hwo to increase the memory leak.
[3452:1014/104426.056:ERROR:service_worker_storage.cc(1904)] Failed to delete the database: Database IO error
(node:21792) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 terminate-timer listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
(Use `electron --trace-warnings ...` to show where the warning was created)
(node:21792) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 set-activity listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
Electron
const electron = require('electron');
const BrowserWindow = electron.BrowserWindow;
const dialog = electron.dialog;
const desktopCapturer = electron.desktopCapturer;
const idle = electron.powerMonitor;
const remote = electron.remote;
const notification = electron.Notification;
const globalShortcut = electron.globalShortcut;
const screen = electron.screen;
const ipcMain = electron.ipcMain;
const app = electron.app;
const isDev = require('electron-is-dev');
const path = require('path');
const activeWindows = require('electron-active-window');
const activeWindowPage = require('active-win');
const BMParser = require('bookmark-parser');
const axios = require('axios');
const uiohook = require('uiohook-napi');
const { autoUpdater } = require("electron-updater");
const debug = require('debug')('Franz:ipcApi:autoUpdate');
const dns = require("dns");
const activity = { is_mouse: 0, is_keyboard: 0 };
const headers = {
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Accept": "application/json"
}
const sessionUser = null;
let updateInterval = null;
app.disableHardwareAcceleration();
electron.powerSaveBlocker.start('prevent-app-suspension');
//electron.commandLine.appendSwitch ("disable-http-cache");
// Change App Name on Windows
if (process.platform === 'win32')
{
app.setAppUserModelId('Rubii');
}
let apiEndpoint = "http://creaz:81/xorix/api"; // Brian
let frameUrl = 'http://localhost:3000'; // Brian
//if (isDev) { // or if(process.env.NODE_ENV)
// apiEndpoint = "http://creaz:81/xorix/api";
// frameUrl = 'http://localhost:3000';
//}
var internetAvailable = require("internet-available");
let isConnected = false;
let counterInternet = 0;
let allowSendInternetNotification = 1;
async function liveInternetCheck() {
var userSessionCheck = await getSessionUser();
// Most easy way
internetAvailable({
domainName: "rubii.com",
// Provide maximum execution time for the verification
timeout: 10000,
// If it tries 10 times and it fails, then it will throw no internet
retries: 10
}).then(() => {
// Available Internet
isConnected = true;
counterInternet++;
if(counterInternet > 3 && allowSendInternetNotification == 0) {
allowSendInternetNotification = 1;
}
}).catch(() => {
// Not available internet
isConnected = false;
if(isConnected == false && userSessionCheck && allowSendInternetNotification == 1) {
var message = 'Your internet has been disconnected! Please login again';
new notification({ title: 'Ooops', body: message }).show();
// Logout the user in the other end
win.webContents.send("terminate-timer", "hello");
allowSendInternetNotification = 0;
counterInternet = 0;
}
});
}
autoUpdater.on("update-available", (_event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Ok'],
title: 'Update Available',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail: 'A new version download started. The app will be restarted to install the update.'
};
dialog.showMessageBox(dialogOpts);
updateInterval = null;
});
autoUpdater.on("update-downloaded", (_event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Restart'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail: 'A new version has been downloaded. Restart the application to apply the updates.'
};
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
});
});
function checkUpdate() {
updateInterval = setInterval(() => autoUpdater.checkForUpdates(), 600000);
}
let win;
ipcMain.on('close-me', (evt, arg) => {
new notification({ title: 'Ooops', body: 'We hope to see you again!' }).show();
app.quit()
});
function determineScreenShotSize() {
var screenSize = screen.getPrimaryDisplay().workAreaSize
return {
width: screenSize.width,
height: screenSize.height
}
}
async function takeScreenshot() {
var user = await getSessionUser();
var timer = await getSessionTimer();
if (user && timer) {
if (timer.timer == 1) {
//console.log('Gathering screens...');
//console.log(app.getPath('pictures'));
const thumbSize = determineScreenShotSize();
const workaroundTimestamp = Date.now();
const options = {
types: ['screen'],
thumbnailSize: { ...thumbSize, workaroundTimestamp }
};
desktopCapturer.getSources(options).then((sources) => {
console.log('Sources received:' + sources.length);
sources.forEach(function (source) {
const sourceName = source.name.toLowerCase();
//console.log(sourceName);
if (['entire screen', 'screen 1'].includes(sourceName)) {
var the_screenshot = source.thumbnail.toPNG();
var data = {
user_id: user.id,
company_id: timer.company_id,
image: the_screenshot.toString('base64')
}
axios.post(apiEndpoint + "/desktop/save_screenshots", data, {
headers: headers
})
.then((response) => {
// console.log(response);
})
.catch((error) => {
//console.log(error);
})
}
})
}).catch(console.error);
}
}
}
function saveSoftware() {
(async () => {
var options = [];
var software = await activeWindowPage();
var user = await getSessionUser();
var timer = await getSessionTimer();
if (user && timer) {
if (timer.timer == 1) {
software.user = user;
software.timer = timer;
axios.post(apiEndpoint + "/desktop/save_app", software, {
headers: headers
})
.then((response) => {
//console.log(response);
})
.catch((error) => {
//console.log(error);
})
}
}
})();
}
function getSessionUser() {
return win.webContents.executeJavaScript('sessionStorage.getItem("user");', true)
.then(result => {
if (result) {
return JSON.parse(result);
}
});
}
function getSessionTimer() {
return win.webContents.executeJavaScript('sessionStorage.getItem("timer");', true)
.then(result => {
if (result) {
return JSON.parse(result);
}
});
}
async function generateActivity() {
win.webContents.send("set-activity", activity);
// We reset after we send it
activity.is_mouse = activity.is_keyboard = 0;
}
function secondsToHms(d) {
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return hDisplay + mDisplay + sDisplay;
}
function createWindow() {
win = new BrowserWindow({
width: 1200,
height: 900,
frame: true,
webPreferences: {
webSecurity: false,
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
backgroundThrottling: false
}
});
//win.loadURL('https://desktop.rubii.com');
win.loadURL(frameUrl, { "extraHeaders": "pragma: no-cache\n" });
// http://localhost:3000
//win.webContents.openDevTools();
//win.removeMenu(); // Brian
// or set the Menu to null
//win.setMenu(null); // Brian
// Reload cache
win.webContents.reloadIgnoringCache();
// Keyboard activity
uiohook.uIOhook.on('keydown', (e) => {
//console.log('Keyboard!')
activity.is_keyboard = 1;
})
// Mouse activity
uiohook.uIOhook.on('mousemove', (e) => {
//console.log('mouse');
activity.is_mouse = 1;
})
// Start listener for keyboard and mouse
uiohook.uIOhook.start();
win.on('close', function () {
win = null;
})
}
app.whenReady().then(createWindow).then(checkUpdate);
app.on('window-all-closed', function () {
app.quit();
});
app.on('activate', function () {
if (win == null) {
createWindow();
}
})
setInterval(takeScreenshot, 10 * 60 * 1000); // 10 minutes
setInterval(saveSoftware, 5 * 1000); // 5 seconds
setInterval(generateActivity, 1 * 1000);
setInterval(function() { liveInternetCheck(); }, 10 * 1000); // 10 seconds
Render
ipcRenderer.on("terminate-timer", function (event, data) {
// Logout if there is no internet connection
handleLogout();
});
// Set activity if there were any keyboard, mouse
ipcRenderer.on("set-activity", function (event, data) {
// If the timer is on
if(timer) {
setActivity(data);
}
});

How can I group(map) by data for ID?

How can I group my data by CustomerID?
It's does not work, I am trying different way but I think I don't understand this structure
This is my code:
function CustomerGroup() {
this.$http.post(auth.API_URL + 'api/ProblemsSupports/ProblemsList', null, {
headers: {
'Authorization': 'Bearer ' + auth.getAuthHeader()
}
}).then((response) => {
this.problemitems = response.body
const map = this.problemitems.map(e => (map[e.CustomerID] = map[e.CustomerID]))
return map
this.progress = false
}, (response) => {
if (response.status === 0) {
this.text1 = ' !!!'
this.snackbar = true
this.progress = false
} else {
this.text1 = '!!!!!!'
this.snackbar = true
this.progress = false
}
})
}
For example you can use this function:
groupBy (list, keyValue) {
const map = new Map()
list.forEach((item) => {
const key = item[keyValue]
const collection = map.get(key)
if (!collection) {
map.set(key, [item])
} else {
collection.push(item)
}
})
return Array.from(map.values())
}
then just call it
const map = groupBy(this.problemitems, 'CustomerID')
You can use function in Vue methods, then don't forget this

How wait a "Array for each" function?

I got a little problem with synchronous/asynchronous system in the function "Array.foreach".
I don't know how to force my code to wait its end.
I tried to use await/async system but my code did not wait the code in "async responseDB =>".
This is my class:
...
let responsesDTO = [];
await Array.prototype.forEach.call(await searchResponsesByQuestionAndUserId(questions[cpt].idquestion, idUser), async responseDB => {
if(responseDB !== undefined){
const responseDTO = {
response_id:0,
response_text:"",
response_type:""
}
const responseEntity = await searchResponseByResponseId(responseDB.response_id);
responseDTO.response_id = responseDB.response_id;
responseDTO.response_text= responseEntity.text;
responseDTO.response_type= responseDB.type;
responsesDTO.push(responseDTO);
}
});
questionResponse.responses=responsesDTO;
questionResponses[cpt]=questionResponse;
}
Could you help me please? Thanks in advance.
I had to mock your async functions. However, the relevant part is to use for..of instead of forEach
async function searchResponsesByQuestionAndUserId() {
let responsesDB = [];
for (let i = 0; i < 10; i++) {
responsesDB.push({
response_id: parseInt(1000 * Math.random(), 10),
type: 'whatever ' + i
});
}
return new Promise((res) => {
window.setTimeout(() => {
res(responsesDB);
}, 1500);
});
}
async function searchResponseByResponseId(response_id) {
return new Promise((res) => {
window.setTimeout(() => {
res({
text: 'text for response ' + response_id
});
}, 300);
});
}
async function getResponsesDTO() {
let responsesDTO = [],
responsesDB = await searchResponsesByQuestionAndUserId();
for (let responseDB of responsesDB) {
if (responseDB === undefined) {
continue;
}
let responseDTO = {
response_id: 0,
response_text: "",
response_type: ""
},
responseEntity = await searchResponseByResponseId(responseDB.response_id);
responseDTO.response_id = responseDB.response_id;
responseDTO.response_text = responseEntity.text;
responseDTO.response_type = responseDB.type;
responsesDTO.push(responseDTO);
console.log({responseDTO});
}
return responsesDTO;
}
getResponsesDTO().then(responsesDTO => {
console.log(responsesDTO);
});

React Native - SetTimeout() is not working. t.apply is not a function

I'm trying to play back audio after a delay of time
_onPlayPausePressed = () => {
if (this.sound != null) {
if (this.state.isPlaying) {
this.sound.pauseAsync();
} else {
setTimeout(this.sound.playAsync(), 2000);
}
}
};
However it returns error: t.apply is not a function. (In't.apply(void 0,o)','t.apply' is undefined)
I tried the updated method of Oleg. It worked the first time but it won't run again after that. Here are more insight of my code:
//import the array with sound details:{id, name desc, sound}
import { soundArray } from "./CreateRecord";
...
export default class CurrentRecord extends React.Component {
constructor(props) {
super(props);
this.currentSound = [];
this.recording = null;
this.sound = null;
this.isSeeking = false;
this.shouldPlayAtEndOfSeek = false;
this.state = {
haveRecordingPermissions: false,
isLoading: false,
isPlaybackAllowed: false,
muted: false,
soundPosition: null,
soundDuration: null,
recordingDuration: null,
shouldPlay: false,
isPlaying: false,
isRecording: false,
fontLoaded: false,
shouldCorrectPitch: true,
volume: 1.0,
rate: 1.0,
isModalVisible: false
};
this.recordingSettings = JSON.parse(
JSON.stringify(Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY)
);
}
//load the audio when the component mount
componentDidMount() {
this.loadAudio();
(async () => {
await Font.loadAsync({
"cutive-mono-regular": require("../../assets/fonts/CutiveMono-Regular.ttf")
});
this.setState({ fontLoaded: true });
})();
this._askForPermissions();
}
//load the sound
async loadAudio() {
const { navigation } = this.props;
const id = navigation.getParam("id");
this.sound = new Audio.Sound();
for (let i = 0; i < soundArray.length; i++) {
if (soundArray[i].id === id) {
this.currentSound = soundArray[i];
console.log(this.currentSound);
break;
}
}
try {
await this.sound.loadAsync({
uri: this.currentSound.sound /* url for your audio file */
});
await this.sound.setOnPlaybackStatusUpdate(
this._updateScreenForSoundStatus
);
} catch (e) {
console.log("ERROR Loading Audio", e);
}
}
//change screen based on the status
_updateScreenForSoundStatus = status => {
if (status.isLoaded) {
this.setState({
soundDuration: status.durationMillis,
soundPosition: status.positionMillis,
shouldPlay: status.shouldPlay,
isPlaying: status.isPlaying,
rate: status.rate,
muted: status.isMuted,
volume: status.volume,
shouldCorrectPitch: status.shouldCorrectPitch,
isPlaybackAllowed: true
});
} else {
this.setState({
soundDuration: null,
soundPosition: null,
isPlaybackAllowed: false
});
if (status.error) {
console.log(`FATAL PLAYER ERROR: ${status.error}`);
}
}
};
_askForPermissions = async () => {
const response = await Permissions.askAsync(Permissions.AUDIO_RECORDING);
this.setState({
haveRecordingPermissions: response.status === "granted"
});
};
//here's where i want to delay the audio file.
_onPlayPausePressed = () => {
if (this.sound != null) {
if (this.state.isPlaying) {
this.sound.pauseAsync();
} else {
setTimeout(() => this.sound.playAsync(), 2000);
}
}
};
_onStopPressed = () => {
if (this.sound != null) {
this.sound.stopAsync();
}
};
_onMutePressed = () => {
if (this.sound != null) {
this.sound.setIsMutedAsync(!this.state.muted);
}
};
_onVolumeSliderValueChange = value => {
if (this.sound != null) {
this.sound.setVolumeAsync(value);
}
};
_trySetRate = async (rate, shouldCorrectPitch) => {
if (this.sound != null) {
try {
await this.sound.setRateAsync(rate, shouldCorrectPitch);
} catch (error) {
// Rate changing could not be performed, possibly because the client's Android API is too old.
}
}
};
_onRateSliderSlidingComplete = async value => {
this._trySetRate(value * RATE_SCALE, this.state.shouldCorrectPitch);
};
_onPitchCorrectionPressed = async value => {
this._trySetRate(this.state.rate, !this.state.shouldCorrectPitch);
};
_onSeekSliderValueChange = value => {
if (this.sound != null && !this.isSeeking) {
this.isSeeking = true;
this.shouldPlayAtEndOfSeek = this.state.shouldPlay;
this.sound.pauseAsync();
}
};
_onSeekSliderSlidingComplete = async value => {
if (this.sound != null) {
this.isSeeking = false;
const seekPosition = value * this.state.soundDuration;
if (this.shouldPlayAtEndOfSeek) {
this.sound.playFromPositionAsync(seekPosition);
} else {
this.sound.setPositionAsync(seekPosition);
}
}
};
_getSeekSliderPosition() {
if (
this.sound != null &&
this.state.soundPosition != null &&
this.state.soundDuration != null
) {
return this.state.soundPosition / this.state.soundDuration;
}
return 0;
}
_getMMSSFromMillis(millis) {
const totalSeconds = millis / 1000;
const seconds = Math.floor(totalSeconds % 60);
const minutes = Math.floor(totalSeconds / 60);
const padWithZero = number => {
const string = number.toString();
if (number < 10) {
return "0" + string;
}
return string;
};
return padWithZero(minutes) + ":" + padWithZero(seconds);
}
_getPlaybackTimestamp() {
if (
this.sound != null &&
this.state.soundPosition != null &&
this.state.soundDuration != null
) {
return `${this._getMMSSFromMillis(
this.state.soundPosition
)} / ${this._getMMSSFromMillis(this.state.soundDuration)}`;
}
return "";
}
_getRecordingTimestamp() {
if (this.state.recordingDuration != null) {
return `${this._getMMSSFromMillis(this.state.recordingDuration)}`;
}
return `${this._getMMSSFromMillis(0)}`;
}
Change to
_onPlayPausePressed = () => {
if (this.sound != null) {
if (this.state.isPlaying) {
this.sound.pauseAsync();
} else {
setTimeout(()=>this.sound.playAsync(), 2000);
}
}
};
Remove execution of function. Also use arrow function(()=> {}) in playAsync
_onPlayPausePressed = async () => {
if (this.sound != null) {
if (this.state.isPlaying) {
await this.sound.pauseAsync();
} else {
setTimeout(() => {
await this.sound.playAsync()
}, 2000);
}
}
};

How to update angular 1.2 service to 1.5 in angular 2 style

https://github.com/snapjay/ngCart/blob/master/src/ngCart.js#L30
I need to update this repo from 1.2 angular to 1.5 and in 2.0 in future
I am start to upgrade this example from addToCart component
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as ngCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive) {//, ngCart
//ngCart object here should service return function?
//angular_angular.js?hash=08f63d2…:13439 TypeError: _apiNgCartNgCart.name.getItemById is not a function
'ngInject';
$reactive(this).attach($scope);
if (this.inCart()) {
this.q = ngCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + ngCart);
return ngCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '#',
name: '#',
quantity: '#',
quantityMax: '#',
price: '#',
data: '='
},
controller: AddToCart
});
and it gives me following error
TypeError: _apiNgCartNgCart.name.getItemById is not a function
at AddToCart.inCart (addToCart.js:39)
and here ngCart service
import { name as ngCartItem } from './ngCartItem';
import { name as store } from './store';
class NgCart {
constructor($scope, $reactive, $window) {
'ngInject';
$reactive(this).attach($scope);
}
$onInit() {
// $rootScope.$on('ngCart:change', function(){ // i shouldn't user rooutscope here
// ngCart.$save();
// });
if (angular.isObject(store.get('cart'))) {
this.$restore(store.get('cart'));
} else {
this.init();
}
}
init() {
this.$cart = {
shipping: null,
taxRate: null,
tax: null,
items: []
};
};
addItem(id, name, price, quantity, data) {
var inCart = this.getItemById(id);
if (typeof inCart === 'object') {
//Update quantity of an item if it's already in the cart
inCart.setQuantity(quantity, false);
// $rootScope.$broadcast('ngCart:itemUpdated', inCart);
} else {
var newItem = new ngCartItem(id, name, price, quantity, data);
this.$cart.items.push(newItem);
// $rootScope.$broadcast('ngCart:itemAdded', newItem);
}
// $rootScope.$broadcast('ngCart:change', {});
};
getItemById(itemId) {
var items = this.getCart().items;
var build = false;
angular.forEach(items, function (item) {
if (item.getId() === itemId) {
build = item;
}
});
return build;
};
setShipping(shipping) {
this.$cart.shipping = shipping;
return this.getShipping();
};
getShipping() {
if (this.getCart().items.length == 0) return 0;
return this.getCart().shipping;
};
setTaxRate(taxRate) {
this.$cart.taxRate = +parseFloat(taxRate).toFixed(2);
return this.getTaxRate();
};
getTaxRate() {
return this.$cart.taxRate
};
getTax() {
return +parseFloat(((this.getSubTotal() / 100) * this.getCart().taxRate)).toFixed(2);
};
setCart(cart) {
this.$cart = cart;
return this.getCart();
};
getCart() {
return this.$cart;
};
getItems() {
return this.getCart().items;
};
getTotalItems() {
var count = 0;
var items = this.getItems();
angular.forEach(items, function (item) {
count += item.getQuantity();
});
return count;
};
getTotalUniqueItems() {
return this.getCart().items.length;
};
getSubTotal() {
var total = 0;
angular.forEach(this.getCart().items, function (item) {
total += item.getTotal();
});
return +parseFloat(total).toFixed(2);
};
totalCost() {
return +parseFloat(this.getSubTotal() + this.getShipping() + this.getTax()).toFixed(2);
};
removeItem(index) {
var item = this.$cart.items.splice(index, 1)[0] || {};
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
removeItemById(id) {
var item;
var cart = this.getCart();
angular.forEach(cart.items, function (item, index) {
if (item.getId() === id) {
item = cart.items.splice(index, 1)[0] || {};
}
});
this.setCart(cart);
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
empty() {
// $rootScope.$broadcast('ngCart:change', {});
this.$cart.items = [];
$window.localStorage.removeItem('cart');
};
isEmpty() {
return (this.$cart.items.length > 0 ? false : true);
};
toObject() {
if (this.getItems().length === 0) return false;
var items = [];
angular.forEach(this.getItems(), function (item) {
items.push(item.toObject());
});
return {
shipping: this.getShipping(),
tax: this.getTax(),
taxRate: this.getTaxRate(),
subTotal: this.getSubTotal(),
totalCost: this.totalCost(),
items: items
}
};
$restore(storedCart) {
var _self = this;
_self.init();
_self.$cart.shipping = storedCart.shipping;
_self.$cart.tax = storedCart.tax;
angular.forEach(storedCart.items, function (item) {
_self.$cart.items.push(new ngCartItem(item._id, item._name, item._price, item._quantity, item._data));
});
this.$save();
};
$save() {
return store.set('cart', JSON.stringify(this.getCart()));
}
}
const name = 'ngCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCartItem,
store
]).service(name, {
controllerAs: name,
controller: NgCart
});
How to import service in 1.5?
I am using angular-meteor and followed this tutorial
And also there can't be scope in service
// This controller throws an unknown provider error because
// a scope object cannot be injected into a service.
https://docs.angularjs.org/error/$injector/unpr?p0=$scopeProvider%20%3C-%20$scope%20%3C-%20ngCart
Found solution
Here how 1.5+ angular service should look like
import { name as store } from './store';
class NgCart {
constructor($reactive, $window) {
'ngInject';
console.log("ngcart service constructor");
}
getItemById (itemId) {
console.log("hello FROM SERVICE!");
}
}
const name = 'NgCart';
// create a module
export default angular.module(name, [
angularMeteor
]).service(name, NgCart);
and how to use it in angular component
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as NgCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive, NgCart) {
'ngInject';
this.NgCart = NgCart;
}
$onInit() {
if (this.inCart()) {
this.q = this.NgCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + this.NgCart);
console.dir(this.NgCart);
return this.NgCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
NgCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '#',
name: '#',
quantity: '#',
quantityMax: '#',
price: '#',
data: '='
},
controller: AddToCart
});
Really helpfull information was in Todd Motto angular 1.x es2015 style guide
for your addToCart component, try this:
import * as angular from 'angular';
import angularMeteor from 'angular-meteor';
import { name as ngCart } from '../../../api/ngCart/ngCart';
import './addToCart.html';
class AddToCart {
constructor($scope, $reactive, ngCart) {
'ngInject';
$reactive(this).attach($scope);
this._ngCart = ngCart;
if (this.inCart()) {
this.q = this._ngCart.getItemById(this.id).getQuantity();
} else {
this.q = parseInt(this.quantity);
}
this.qtyOpt = [];
for (var i = 1; i <= this.quantityMax; i++) {
this.qtyOpt.push(i);
}
}
inCart() {
console.log("cart " + ngCart);
return this._ngCart.getItemById(this.id);
}
}
const name = 'addToCart';
// create a module
export default angular.module(name, [
angularMeteor,
ngCart
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
bindings: {
id: '#',
name: '#',
quantity: '#',
quantityMax: '#',
price: '#',
data: '='
},
controller: AddToCart
});
for your service, try this (services don't have scope):
import { name as ngCartItem } from './ngCartItem';
import { name as store } from './store';
class NgCart {
$onInit() {
// $rootScope.$on('ngCart:change', function(){ // i shouldn't user rooutscope here
// ngCart.$save();
// });
if (angular.isObject(store.get('cart'))) {
this.$restore(store.get('cart'));
} else {
this.init();
}
}
init() {
this.$cart = {
shipping: null,
taxRate: null,
tax: null,
items: []
};
};
addItem(id, name, price, quantity, data) {
var inCart = this.getItemById(id);
if (typeof inCart === 'object') {
//Update quantity of an item if it's already in the cart
inCart.setQuantity(quantity, false);
// $rootScope.$broadcast('ngCart:itemUpdated', inCart);
} else {
var newItem = new ngCartItem(id, name, price, quantity, data);
this.$cart.items.push(newItem);
// $rootScope.$broadcast('ngCart:itemAdded', newItem);
}
// $rootScope.$broadcast('ngCart:change', {});
};
getItemById(itemId) {
var items = this.getCart().items;
var build = false;
angular.forEach(items, function (item) {
if (item.getId() === itemId) {
build = item;
}
});
return build;
};
setShipping(shipping) {
this.$cart.shipping = shipping;
return this.getShipping();
};
getShipping() {
if (this.getCart().items.length == 0) return 0;
return this.getCart().shipping;
};
setTaxRate(taxRate) {
this.$cart.taxRate = +parseFloat(taxRate).toFixed(2);
return this.getTaxRate();
};
getTaxRate() {
return this.$cart.taxRate
};
getTax() {
return +parseFloat(((this.getSubTotal() / 100) * this.getCart().taxRate)).toFixed(2);
};
setCart(cart) {
this.$cart = cart;
return this.getCart();
};
getCart() {
return this.$cart;
};
getItems() {
return this.getCart().items;
};
getTotalItems() {
var count = 0;
var items = this.getItems();
angular.forEach(items, function (item) {
count += item.getQuantity();
});
return count;
};
getTotalUniqueItems() {
return this.getCart().items.length;
};
getSubTotal() {
var total = 0;
angular.forEach(this.getCart().items, function (item) {
total += item.getTotal();
});
return +parseFloat(total).toFixed(2);
};
totalCost() {
return +parseFloat(this.getSubTotal() + this.getShipping() + this.getTax()).toFixed(2);
};
removeItem(index) {
var item = this.$cart.items.splice(index, 1)[0] || {};
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
removeItemById(id) {
var item;
var cart = this.getCart();
angular.forEach(cart.items, function (item, index) {
if (item.getId() === id) {
item = cart.items.splice(index, 1)[0] || {};
}
});
this.setCart(cart);
// $rootScope.$broadcast('ngCart:itemRemoved', item);
// $rootScope.$broadcast('ngCart:change', {});
};
empty() {
// $rootScope.$broadcast('ngCart:change', {});
this.$cart.items = [];
$window.localStorage.removeItem('cart');
};
isEmpty() {
return (this.$cart.items.length > 0 ? false : true);
};
toObject() {
if (this.getItems().length === 0) return false;
var items = [];
angular.forEach(this.getItems(), function (item) {
items.push(item.toObject());
});
return {
shipping: this.getShipping(),
tax: this.getTax(),
taxRate: this.getTaxRate(),
subTotal: this.getSubTotal(),
totalCost: this.totalCost(),
items: items
}
};
$restore(storedCart) {
var _self = this;
_self.init();
_self.$cart.shipping = storedCart.shipping;
_self.$cart.tax = storedCart.tax;
angular.forEach(storedCart.items, function (item) {
_self.$cart.items.push(new ngCartItem(item._id, item._name, item._price, item._quantity, item._data));
});
this.$save();
};
$save() {
return store.set('cart', JSON.stringify(this.getCart()));
}
}
const name = 'ngCart';
export default angular.module(name, [
angularMeteor,
ngCartItem,
store
]).service(name, NgCart);

Resources