How to get a property when setting others in Object Literal notation? - javascript

In java script I get this error
Uncaught ReferenceError: baseUrl is not defined
window.Configurations = Configurations = {
baseUrl: 'https://mysite.com/',
detailsEventCustom: baseUrl + 'DetailsEventCustom?EventId=',
addEventCustom: baseUrl + 'AddEventCustom',
listAllEventsCustomForDate: baseUrl + 'ListAllEventsCustomForDate?DateToLookUp=',
dashboardEventsCustom: baseUrl + 'DashboardEventsCustom',
listAllTimetableEventsCustom: baseUrl + 'ListAllTimetableEventsCustom',
updateEventCustom: baseUrl + 'UpdateEventCustom?EventId=',
deleteEventCustom: baseUrl + 'DeleteEventCustom?EventId='
};
Could you point me out what I am doing wrong here?

you cannot do it like this
when you are accessing the object hasn't been made try doing this instead
var baseUrl = 'https://mysite.com/';
window.Configurations = Configurations = {
baseUrl: baseUrl,
detailsEventCustom: baseUrl + 'DetailsEventCustom?EventId=',
addEventCustom: baseUrl + 'AddEventCustom',
listAllEventsCustomForDate: baseUrl + 'ListAllEventsCustomForDate?DateToLookUp=',
dashboardEventsCustom: baseUrl + 'DashboardEventsCustom',
listAllTimetableEventsCustom: baseUrl + 'ListAllTimetableEventsCustom',
updateEventCustom: baseUrl + 'UpdateEventCustom?EventId=',
deleteEventCustom: baseUrl + 'DeleteEventCustom?EventId='
};

This is a scoping problem. You are still building the object between the curly braces, and all values are calculated before they are assigned to the object. baseUrl simply doesn't exist yet when you are using it to assign the other values. You should do something like this instead:
var baseUrl = 'https://mysite.com/'
window.Configurations = Configurations = {
baseUrl: baseUrl,
detailsEventCustom: baseUrl + 'DetailsEventCustom?EventId=',
addEventCustom: baseUrl + 'AddEventCustom',
listAllEventsCustomForDate: baseUrl + 'ListAllEventsCustomForDate?DateToLookUp=',
dashboardEventsCustom: baseUrl + 'DashboardEventsCustom',
listAllTimetableEventsCustom: baseUrl + 'ListAllTimetableEventsCustom',
updateEventCustom: baseUrl + 'UpdateEventCustom?EventId=',
deleteEventCustom: baseUrl + 'DeleteEventCustom?EventId='
};

Related

ReferenceError: Invalid left-hand side in assignment at Object

Trying to finish an OAuth2 flow, but keep getting an uncaught referenceerror. Fairly new to Node.js and cant seem to find out what's going on.
// require the blockspring package.
var blockspring = require('blockspring');
var request = require('request');
// pass your function into blockspring.define. tells blockspring what function to run.
blockspring.define(function(request, response) {
// retrieve input parameters and assign to variables for convenience.
var buffer_clientid = request.params["buffer_clientid"];
var buffer_secret = request.params["buffer_secret"];
var redirectURI = request.params["redirectURI"];
var tokencode = request.params["tokencode"];
request({
method: "POST",
url: "https://api.bufferapp.com/1/oauth2/token.json",
headers: {
'User-Agent': 'request',
},
body: client_id=buffer_clientid&client_secret=buffer_secret&redirect_uri=redirectURI&code=tokencode&grant_type=authorization_code
}, function(error, response, body){
console.log(body);
// return the output.
response.end();
});
});
That's not valid JavaScript syntax:
body: client_id=buffer_clientid&client_secret=buffer_secret&redirect_uri=redirectURI&code=tokencode&grant_type=authorization_code
I'm assuming you are trying to concatenate your variable values to a string? Try this instead:
body: "client_id=" + buffer_clientid + "&client_secret=" + buffer_secret + "&redirect_uri=" + redirectURI + "&code=" + tokencode + "&grant_type=" +authorization_code
Strings in nodejs need to be quoted. In your request function, you're passing a key of body, with a value of what appears to be a giant variable. Because there are no quotes around client_id=buffer_clientid&client_secret=buffer_secret&redirect_uri=redirectURI&code=tokencode&grant_type=authorization_code, it's trying to treat this as a variable. When the parser gets to the = sign, it's trying to then set client_id = the following. This is throwing the error.
Simply quote the entire string or if you need to use variables concat using 'string' + variable + 'string'.
Judging by your variable names, you can simple rewrite it as follows:
request({
method: "POST",
url: "https://api.bufferapp.com/1/oauth2/token.json",
headers: {
'User-Agent': 'request',
},
body: 'client_id=' + buffer_clientid + '&client_secret=' + buffer_secret + '&redirect_uri=' + redirectURI + '&code=' + tokencode + '&grant_type=authorization_code'
}, function(error, response, body){
console.log(body);
// return the output.
response.end();
})

Override cached image in ajax response

I have an ajax response that is returning images that are cached. I can bust this cache with a random number generator, but having an issue applying it correctly to the returned URI.
The cached image has a URI coming from the response represented by "obj.entity.entries[property].uri" that looks like this:
http://xx.domain.com/api/v2/img/5550fdfe60b27c50d1def72d?location=SQUARE
The newly uploaded image needs to have the random number applied to it, so that it is appended to the end of the URI, right before the ?, like so:
http://xx.domain.com/api/v2/img/5550fdfe60b27c50d1def72d+6?location=SQUARE, where +6 is the randomly generated number.
I believe the best approach is to use a regex to look for the end of the URI before the ? and apply the var storing the random number, then reapply this new URI to the response. I have the following worked out, but not sure how to apply the regex correctly:
$('.image-search').on('click', function () {
var root = "http://localhost:7777/proxy/staging/rest/v1/cms/story/id/";
var encodeID = $("#imageid").val();
var bearerToken = localStorage.getItem('Authorization');
var imageCacheBust = Math.floor((Math.random() * 10) + 1);
//IF TESTING ON LOCALHOST
if (document.domain == 'localhost') {
url = root + encodeID + "/images";
} else {
//IF IN PRODUCTION
url = "/cropper/admin/cropv2/rest/v1/cms/story/id/" + encodeID + "/images";
//GRAB REFERRER URL FOR VIMOND ASSET
//SET VALUE SUCCEEDING ASSETS AS ASSET ID
var regexp = /assets\/(\d+)/;
var assetid = regexp.exec(window.document.referrer);
$("#imageid").val(assetid[1]);
};
$.ajax({
url: url,
method: 'GET',
headers: {
"Authorization": bearerToken
},
}).then(function (response) {
var obj = response;
var regexp = "REGEX HERE";
var imageURI = regexp.exec(obj.entity.entries[property].uri);
$("#imageid").css("border-color", "#ccc");
$(".search-results").empty();
for (var property in obj.entity.entries) {
if (obj.entity.entries.hasOwnProperty(property)) {
$(".search-results").append($("<li><a href='" + imageURI + "' target='_blank'><div class='thumbnail'><img width='30' height='30' src='" + imageURI + "' target='_blank'/></img><div class='caption'><p>" + obj.entity.entries[property].orientation + "</p></div></a></li>"));
}
}
}).fail(function (data) {
$(".search-results").empty();
$(".search-results").append("<p class='alert alert-danger'>Invalid ID</p>");
$("#imageid").css("border-color", "red");
});
});
You don't need to add your random digits to the file path part of the URL, just append to the URL parameters instead, that is enough to prevent caching.
For example use:
img/5550fdfe60b27c50d1def72d?location=SQUARE&6
Where the 6 is your randomly generated value.
Also, be aware that a randomly generated number might not be the best choice here, since it might be undesirably duplicated. Consider using a hash or timestamp instead of a purely random number.
The solution ended up being fairly simple:
I set var imageCacheBust = Math.random(); and then used it in the returned URI like so: var imageURI = obj.entity.entries[property].uri + "?" + imageCacheBust;

How to disable certain HTTP methods (e.g. POST) for PersistedModel in LoopBack framework

When you create model in LoopBack framework, you can inherit from PersistedModel class. This way all the HTTP methods are generated. I am wondering how can I disable certain HTTP methods?
One option is to override functions from PersistedModel with empty logic, but want method to disappear from Swagger API explorer.
I did below in model.js files like below. This makes table readonly.
module.exports = function(model) {
var methodNames = ['create', 'upsert', 'deleteById','updateAll',
'updateAttributes','createChangeStream','replace','replaceById',
'upsertWithWhere','replaceOrCreate'
];
methodNames.forEach(function(methodName) {
disableMethods(model,methodName)
});
}
function disableMethods(model,methodName)
{
if(methodName!='updateAttributes')
model.disableRemoteMethod(methodName, true);
else
model.disableRemoteMethod(methodName, false);
}
The only thing which requires additional care is disabling of custom model methods (like User.login). You need to call disableRemoteMethod before explorer middleware: https://github.com/strongloop/loopback/issues/686
An update on Santhosh Hirekerur answer to make it hide everything on LB3, stop using the deprecated Model.disableRemoteMethod method and also a more intelligent way to hide updateAttributes and any other future methods that may work the same.
I check to see if the method is on the prototype and if it is, prefix the name with prototype. before we disableRemoteMethodByName:
module.exports = function (model) {
var methodNames = [
'create',
'upsert',
'deleteById',
'updateAll',
'updateAttributes',
'patchAttributes',
'createChangeStream',
'findOne',
'find',
'findById',
'count',
'exists',
'replace',
'replaceById',
'upsertWithWhere',
'replaceOrCreate'
];
methodNames.forEach(function (methodName) {
if (!!model.prototype[methodName]) {
model.disableRemoteMethodByName('prototype.' + methodName);
} else {
model.disableRemoteMethodByName(methodName);
}
});
}
I put the above code in server/middleware/disable-methods.js and call it from a model like so:
var disableMethods = require('../../server/middleware/disable-methods');
module.exports = function (Model) {
disableMethods(Model);
}
Found answer in documentation.
For example this disables PersistedModel.deleteById:
var isStatic = true;
MyModel.disableRemoteMethod('deleteById', isStatic);
So it looks like you it's not possible to disable all DELETE actions at the same time. For example method PersistedModel.deleteAll remains accessible in given example.
Developer must disable each relevant method from PersistedModel class explicitly.
Relevant docs are here
Sections:
Hiding methods and REST endpoints
Hiding endpoints for related models
In case of loopback 3
I had the same problem.
My first solution was to manually update the "public":true items in server/model-configuration.json but it was overridden anytime I used the Swagger tool to refresh the LoopBack API (with slc loopback:swagger myswaggerfilename command from the project root).
I finally wrote a Grunt task as a reliable workaround.
Run it just after a slc loopback:swagger generation or just before running the API live.
you just have to specify the names of the paths I want to expose in the javascript array list_of_REST_path_to_EXPOSE
and make sure you are happy with the backup folder for the original /server/model-config.json file.
I wanted to share it with you in case:
https://github.com/FranckVE/grunt-task-unexpose-rest-path-loopback-swagger
Basically:
module.exports = function (grunt) {
grunt.registerTask('unexpose_rest_path_for_swagger_models_v1', function (key, value) {
try {
// Change the list below depending on your API project :
// list of the REST paths to leave Exposed
var list_of_REST_path_to_EXPOSE =
[
"swagger_example-api_v1",
"write_here_the_paths_you_want_to_leave_exposed"
];
// Location of a bakup folder for modified model-config.json (change this according to your specific needs):
var backup_folder = "grunt-play-field/backups-model-config/";
var src_folder = "server/";
var dest_folder = "server/";
var src_file_extension = ".json";
var src_file_root_name = "model-config";
var src_filename = src_file_root_name + src_file_extension;
var dest_filename = src_file_root_name + src_file_extension;
var src = src_folder + src_filename;
var dest = dest_folder + dest_filename;
var free_backup_file = "";
if (!grunt.file.exists(src)) {
grunt.log.error("file " + src + " not found");
throw grunt.util.error("Source file 'model-config.json' does NOT exists in folder '" + src_folder + "'");
}
// timestamp for the backup file of model-config.json
var dateFormat = require('dateformat');
var now = new Date();
var ts = dateFormat(now, "yyyy-mm-dd_hh-MM-ss");
// backup model-config.json
var root_file_backup = src_file_root_name + "_bkp" + "_";
var root_backup = backup_folder + root_file_backup;
free_backup_file = root_backup + ts + src_file_extension;
if (!grunt.file.exists(root_file_backup + "*.*", backup_folder)) {
//var original_file = grunt.file.read(src);
grunt.file.write(free_backup_file, "// backup of " + src + " as of " + ts + "\n");
//grunt.file.write(free_backup_file, original_file);
grunt.log.write("Creating BACKUP"['green'] + " of '" + src + "' " + "to file : "['green'] + free_backup_file + " ").ok();
} else {
grunt.log.write("NO BACKUP created"['red'] + " of '" + src + "' " + "because file : " + free_backup_file + " ALREADY EXISTS ! "['red']).error();
throw grunt.util.error("Destination backup file already exists");
}
// load model-config.json
var project = grunt.file.readJSON(src);//get file as json object
// make modifications in model-config.json
for (var rest_path in project) {
if (rest_path.charAt(0) === "_") {
grunt.log.write("SKIPPING"['blue'] + " the JSON item '" + rest_path + "' belonging to the " + "SYSTEM"['blue'] + ". ").ok();
continue; // skip first level items that are system-related
}
if (list_of_REST_path_to_EXPOSE.indexOf(rest_path) > -1) { //
project[rest_path]["public"] = true;
grunt.log.write("KEEPING"['green'] + " the REST path '" + rest_path + "' " + "EXPOSED"['green'] + ". ").ok();
} else {
project[rest_path]["public"] = false;
grunt.log.writeln("HIDING"['yellow'] + " REST path '" + rest_path + "' : it will " + "NOT"['yellow'] + " be exposed.");
}
}
}
I wanted to hide the PATCH method, but when I was trying to hide it also I got to hide the PUT method , I was using this line :
Equipment.disableRemoteMethod('updateAttributes', false);
but later I found a way to only hide the PATCH method, this line works perfect for me.
Equipment.sharedClass.find('updateAttributes', false).http = [{verb: 'put', path: '/'}];
The above line overrides the original http that updateAttributes method had.
[{verb: 'put', path: '/'}, {verb: 'patch', path: '/'}]

How to define property at runtime in nodejs

I have the following property defined for my database access in nodejs. The problem is that I need also the url parameter defined for a certain function. I have therefore written the helper function getDataUrl()
var config = {
db: {
db: 'dbname', // the name of the database
host: "12.12.12.12", // the ip adress of the database
port: 10091, // the port of the mongo db
username: "name", //the username if not needed use undefined
password: "pw", // the password for the db access
url: undefined // also tried url: getDataUrl()
}
};
function getDataUrl() {
var dataUrl = "mongodb://";
if (config.db.username !== undefined) {
dataUrl += config.db.username + ':' + config.db.password + '#';
}
dataUrl += config.db.host + ":" + config.db.port;
dataUrl += '/' + config.db.db
return dataUrl;
}
module.exports = config;
However I do not want to call this function but use instead the property config.db.url.
I am at the moment struggling how to do that. I have tried the following:
write url: getDataUrl() this produce: TypeError: Cannot read property 'db' of undefined
call getDataUrl() which then writes the property, however this does not overwrite the url property. When I then read the value the following error occures: Cannot read property 'url' of undefined
write config.db.url = getDataUrl(); this also does not overwrite the url property.
I am very new to JavaScript and nodejs therefore I do not know how to achieve this behavior or if it is even possible.
You could try a getter property:
var config = {
db: {
db: 'dbname', // the name of the database
host: "12.12.12.12", // the ip adress of the database
port: 10091, // the port of the mongo db
username: "name", //the username if not needed use undefined
password: "pw", // the password for the db access
get url() {
var dataUrl = "mongodb://";
if (this.username)
dataUrl += this.username + ':' + this.password + '#';
dataUrl += this.host + ":" + this.port + '/' + this.db;
return dataUrl;
}
}
};
console.log(config.db.url); // automatically computed on [every!] access
To fix
write url: getDataUrl() this produce: TypeError: Cannot read property
'db' of undefined
you should change the "configs" variable to "config" in your getDataUrl() function:
function getDataUrl() {
var dataUrl = "mongodb://";
if (config.db.username !== undefined) {
dataUrl += config.db.username + ':' + config.db.password + '#';
}
dataUrl += config.db.host + ":" + config.db.port;
dataUrl += '/' + config.db.db
return dataUrl;
}

Object literals concatenate string attributes

I'm using Javascript Object literals , but i can't concatenate string attributes.
var cart = {
baseURL : "http://www.domain.com/",
addURL : this.baseURL + "cart/add",
deleteURL : this.baseURL + "cart/delete",
totalURL : this.baseURL + "cart/total",
// functions
}// cart
i get a link as http://www.domain.com/undefinedcart/add
Please any help,
Thanks in advance
You don't have access to the baseURL in that way. Thats because this is actually window and it probably does not has property baseURL.
You can use Immediately-Invoked Function Expression (IIFE) and closure instead:
var cart = function () {
var baseURL = "http://www.domain.com/";
return {
addURL : baseURL + "cart/add",
deleteURL : baseURL + "cart/delete",
totalURL : baseURL + "cart/total"
};
}();
The problem isn't concatenation within the context of the object, it's that the this you're looking for doesn't exist yet. A simple solution might look like this:
var baseURL = "http://www.domain.com/";
var cart = {
baseURL : baseURL,
addURL : baseURL + "cart/add",
deleteURL : baseURL + "cart/delete",
totalURL : baseURL + "cart/total",
}
Or this:
var cart = new function() {
this.baseURL = "http://www.domain.com/";
this.addURL = this.baseURL + "cart/add";
this.deleteURL = this.baseURL + "cart/delete";
this.totalURL = this.baseURL + "cart/total";
};
The variable "this" is a instance of Window, so you can't use "this" as "cart"

Categories

Resources