How to get specific data from API and use in function? - javascript

I'm trying to build a weather app in nodejs with dark-sky API. I got a separate js file and keep my forecast info in a callback function. However, I also want to use Skycons for visualization.
this is my forecast.js. in that script I get info like temperature etc. so I need to get "icon" data as well
const request = require('request')
const getWeather = (latitude, longitude, callback) => {
const url = 'https://api.darksky.net/forecast/b0854aec02e1655c7203e05c7d77dfd1/' + latitude + ',' + longitude + '/?units=si'
request({
url: url,
json: true
}, (error, {
body /* "response " evezine response object icindeki "body" birbasa daxil edirem function-a*/
}) => {
if (error) {
callback('Unable to connect to weather service!', undefined)
} else if (body.error) {
callback('Unable to find location'.undefined)
} else {
callback(undefined,
'It is currently ' + body.currently.temperature + '°C out in ' + body.timezone + '. Weather ' + body.daily.data[0].summary + ' There is a ' + (body.currently.precipProbability * 100) + '% chance of rain.'
)
}
})
}
module.exports = getWeather
This is the fetch function, and I tried to invoke and activate Skycons in this function. but I cannot get "icon" data from API.
const weatherForm = document.querySelector("form");
const search = document.querySelector("input");
const messageOne = document.querySelector("#message-1");
const messageTwo = document.querySelector("#message-2");
const skycons = new Skycons({
color: '#222'
})
skycons.set('icon', 'clear-day');
skycons.play();
const icon = data.forecast.icon;
weatherForm.addEventListener("submit", e => {
e.preventDefault();
const location = search.value;
messageOne.textContent = "Please wait....";
messageTwo.textContent = "";
fetch(
"http://localhost:4000/weather?address=" + encodeURIComponent(location)
).then(response => {
response.json().then(data => {
if (data.error) {
messageOne.textContent = data.error;
} else {
messageOne.textContent = data.location;
messageTwo.textContent = data.forecast;
}
currentSkycons(icon, document.getElementById('icon'));
});
});
messageOne.textContent;
messageTwo.textContent;
});
function currentSkycons(icon, iconID) {
const currentIcon = icon.replace(/-/g, "_").toUppercase();
skycons.play();
return skycons.set(iconID, Skycons[currentIcon]);
}
but to use Skycons, I need to get "icon" from the dark-sky API. how I can get this data aside from my forecast js? To get and assign that data to a variable and use in another function

It looks like the data object is only accessible in the response json, which means you would need to access forcast.icon when you have the response.

Related

How to turn do make these function in to chaining function?

Am trying to use the chaining method but am not sure how to that yet. I have researched online and still haven't found any success any help will be appreciated.
// The URL root if user searches by city
const API_ROOT_CITY = "http://api.geonames.org/searchJSON?q=";
// Parameters for geonames
const API_ROOT_PARAMS = "&maxRows=1"
// API KEY for geonames
const API_KEY = &username=kamara.moses;
// WeatherBit URL
const API_ROOT_BIT = "https://api.weatherbit.io/v2.0/forecast/daily?"
// Parameters for weatherbit
const API_BIT_PARAMS = "&city="
// API KEY for weatherbit
const API_BIT_KEY = "&key=cda6df51d9a24b8c9d54b830f4eadb51"
// PixaBay URL
const API_ROOT_PIXA = "https://pixabay.com/api/?"
// API KEY for pixabay
const API_PIXA_KEY = "key=19853981-85155ca595da994be43f034e6"
// Parameters for pixabay
const API_PIXA_PARAMS = "&q="
// Type of image from pixabay
const API_PIXA_IMAGE = "&image_type=photo"
// Main function of the program
// Grabs the user"s input, then forms URL, calls API, POSTS and updates UI
function clickRespond() {
// Grab user"s input
const cityInput = document.getElementById("city");
// Read values of zip and city
const city = cityInput.value;
// Form URL based on zip or city search
// (zip takes precendence if both were entered)
let url;
let bitURL;
let pixaURL;
if (city) {
url = API_ROOT_CITY + city + API_ROOT_PARAMS + API_KEY;
bitURL = API_ROOT_BIT + API_BIT_PARAMS + city + API_BIT_KEY;
pixaURL = API_ROOT_PIXA + API_PIXA_KEY + API_PIXA_PARAMS + API_PIXA_IMAGE;
}
// Call the API
getGeo(url)
// Prepares data for POST, calls the POST
.then(function (response) { // CHANGE: call it response
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") { // CHANGE: check the status
errorMessage.classList.add("hide");
const city = response.geoNames.geonames[0].name; // Change
postJournal("/add", { city }) ;
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
getWeather(bitURL)
.then(function (response) {
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") {
errorMessage.classList.add("hide");
const icon = response.weatherBit.data[0].weather.icon;
const description = response.weatherBit.data[0].weather.description
const newDate = dateTime();
const date = newDate;
const highTemp = response.weatherBit.data[0].high_temp;
const lowTemp = response.weatherBit.data[0].low_temp
postJournal("/add", { icon: icon, description: description, date: date, highTemp: highTemp, lowTemp: lowTemp });
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
getPix(pixaURL)
.then(function (response) {
console.log(response)
const errorMessage = document.getElementById("error");
if (response.status == "200") {
errorMessage.classList.add("hide");
const image = response.pixaBay.hits[0].webformatURL;
postJournal("/add", { image: image });
// Calls to update the site with latest entry
updateUI();
} else {
console.log("Bad data entered");
errorMessage.classList.remove("hide");
return;
}
})
}

How to SEND the content when making a GET in Javascript?

I need to GET all the data of a workbook, and I tried one method, but it does not work properly.. The problem is that the Promise is returning the first line of the first worksheet, but it does not continue the process for the rest of the rows of the worksheet, respectively, all the worksheets and I don't know what to do. Maybe you know..
So I wrote this code:
const SheetGet = {
getSheet: (req, res) => {
return new Promise ((resolve, reject) => {
XlsxPopulate.fromFileAsync(filePath)
.then(workbook => {
const wb = xlsx.readFile(filePath, {cellDates: true});
const sheetNames = wb.SheetNames;
sheetNames.forEach(function (element){
let endOfData = false;
let i = 2;
let dataArr = [];
while (endOfData === false){
let taskId = workbook.sheet(element).cell("A" + i.toString()).value();
if (taskId !== undefined){
res.send({
type: 'GET',
list_name: element,
task_id: taskId,
task_name: workbook.sheet(element).cell("B" + i.toString()).value(),
task_description: workbook.sheet(element).cell("C" + i.toString()).value(),
task_due_date: workbook.sheet(element).cell("D" + i.toString()).value(),
task_priority: workbook.sheet(element).cell("E" + i.toString()).value(),
task_status: workbook.sheet(element).cell("F" + i.toString()).value(),
task_notes: workbook.sheet(element).cell("G" + i.toString()).value()
});
i++;
}
else {
endOfData = true;
}
}
})
});
})
}
}
It only gets this an then it stops, and I need to get all of the data from the worksheet.
Do you have any idea on how to resolve this issue? Or the proper way to make it work? Thank you very very much for your time and help!!! Much appreciated every help!!
P.S. I tried this code with "console.log", and it works very well, but the problem is when I changed to res.send, in order to get the info to Postman.
I assume you are using express as the framework, the problem is when you use res.send method, the server already send the data to client, while the rest of the code still running in the background. What I'm gonna do with this case are like this.
const SheetGet = {
getSheet: (req, res) => {
return new Promise ((resolve, reject) => {
XlsxPopulate.fromFileAsync(filePath)
.then(workbook => {
const wb = xlsx.readFile(filePath, {cellDates: true});
const sheetNames = wb.SheetNames;
sheetNames.forEach(function (element){
let endOfData = false;
let i = 2;
let dataArr = [];
while (endOfData === false){
let taskId = workbook.sheet(element).cell("A" + i.toString()).value();
if (taskId !== undefined){
dataArr.push({ // this one
type: 'GET',
list_name: element,
task_id: taskId,
task_name: workbook.sheet(element).cell("B" + i.toString()).value(),
task_description: workbook.sheet(element).cell("C" + i.toString()).value(),
task_due_date: workbook.sheet(element).cell("D" + i.toString()).value(),
task_priority: workbook.sheet(element).cell("E" + i.toString()).value(),
task_status: workbook.sheet(element).cell("F" + i.toString()).value(),
task_notes: workbook.sheet(element).cell("G" + i.toString()).value()
});
i++;
}
else {
endOfData = true;
}
}
})
return res.json({ data: dataArr }); // this one
});
})
}
}
While there is some unnecessary code, the least change you can do to make it works are the code above.
Cheers.

How to delete image with image uri in React Native?

I am trying to develop a simple app.This app posts a multipart form data with image and some text field. I am picking the image using react-native-image-picker. My App works fine. But i noticed it is not clearing the images. That is why the size of my app is increasing. If i go to General>Iphone storage, i can see my app size increasing.
I have tried the following code to delete the image but it did not work.
import RNFetchBlob from 'react-native-fetch-blob';
RNFetchBlob.fs.unlink(imageuri)
.then(() => {
console.log('file deleted!');
});
I think RnFetchBlob needs the actual file path.The code of my upload function is given below.
upload() {
var new_state = this.state;
var image_array = this.state.imageArray;
var comment = this.state.main_comment;
var new_state = this.state;
new_state.loader_show = !new_state.loader_show;
this.setState(new_state);
navigator.geolocation.getCurrentPosition(position => {
var lat = parseFloat(position.coords.latitude);
var lon = parseFloat(position.coords.longitude);
var new_state = this.state;
new_state.lat = lat;
new_state.lon = lon;
});
var position = "position(" + this.state.lat + "," + this.state.lon + ")";
for (var i = 0; i < image_array.length; i++) {
var file_name = position + "-" + i;
const data = new FormData();
data.append("name", file_name);
data.append("comment", comment); // you can append anyone.
data.append("images", {
uri: image_array[i].uri,
type: "image/jpeg", // or photo.type
name: "testPhotoName"
});
fetch("#####", {
method: "post",
body: data
})
.then(res => {
alert("Successfully uploaded from " + position);
************************* Here I want to Delete the file *******
RNFetchBlob.fs.unlink(image_array[i].uri).then(() => {
console.log("file deleted!");
});
****************************************************************
})
.catch(err => {
// ...
alert(err);
});
}
Please be informed that i store the image uri in my state. I dont have the Local file path.I want to delete the image using the uri after the upload is done.
I solved my problem. The below code worked for me.
var uri = images[i].uri;
var path = uri.split("///").pop();
RNFetchBlob.fs
.unlink(path)
.then(() => {
alert("File deleted");
})
.catch(err => {
alert(err);
});

Transformation which split document and insert as multiple

The only way i found to do it through MLCP, where you transformation has to return an array of format [{"uri": "some_uri1", "value": "newly_created_doc1"},{"uri": "some_uri2", "value": "newly_created_doc2"}]. This way after applying transformation with content pump there will be created these two documents from let's say some original document. My question is how to achieve the same result via node.js api or java api. For example with node.js I am able to apply transformation and it is creating this file as a single document with array of the style above.
My transformation:
const common = require("/ext/home/common.sjs");
function createDocs(content, context) {
var bets = content.value.xpath('//selections').toArray();
var documents = [];
for (var bet in bets) {
var bookie_name = "Boylesports";
var sport_name = "Football";
var event_name = bets[bet].xpath('../../../../name').toString();
if (/^Over \d+\.\d+$/.test(event_name)) {
event_name = event_name.replace(/^Over (\d+)\.\d+$/, 1);
} else {
event_name;
}
var subevent_name = bets[bet].xpath('../../../../name').toString();
if (/^Over \d+\.\d+$/.test(subevent_name)) {
subevent_name = subevent_name.replace(/^Over (\d+)\.\d+$/, 1);
}
else {
subevent_name;
}
var subevent_id = bets[bet].xpath('../../../../idfoevent');
var start_date = xdmp.parseDateTime("[Y0001]-[M01]-[D01]T[h01]:[m01]:[s01]", bets[bet].xpath('../../../../tsstart'));
// var start_date = "2017-10-21T13:00:00Z";
var market_name = bets[bet].xpath('../../name').toString();
if (/^Handicap.+$/.test(market_name)) {
market_name = market_name.replace(/^Handicap.+$/, "Handicaps");
}
if (/^Match Betting$/.test(market_name)) {
market_name = market_name.replace(/^Match Betting$/, "Win Market");
}
else {
market_name;
}
var market_id = bets[bet].xpath('../../idfomarket');
var bet_name = bets[bet].xpath('name').toString();
if (/^Aston Villa$/.test(bet_name)) {
bet_name = bet_name.replace(/^Aston (Villa)$/, 1);
}
else {
bet_name;
}
var bet_id = bets[bet].xpath('idfoselection');
//Push to the list of documents
var document = {};
document.uri = common.convertToSlug(sport_name) + '/' + common.convertToSlug(event_name) + '/' + common.convertToSlug(subevent_name) + '/' + common.convertToSlug(market_name) + '/' + common.convertToSlug(bet_name);
document.value = {
'bookie_name': bookie_name,
'sport_name': sport_name,
'sport_slug': common.convertToSlug(sport_name),
'event_name': event_name,
'event_slug': common.convertToSlug(event_name),
'subevent_name': subevent_name,
'subevent_slug': common.convertToSlug(subevent_name),
'subevent_id': subevent_id,
'start_date': start_date,
'market_name': market_name,
'market_slug': common.convertToSlug(market_name),
'market_id': market_id,
'bet_name': bet_name,
'bet_slug': common.convertToSlug(bet_name),
'bet_id': bet_id
};
//Checks if objects with the same uri exist before pushing them
if (documents.findIndex(x => x.uri == document.uri) === -1) documents.push(document);
// documents.push(document);
}
return Sequence.from(documents);
};
exports.transform = createDocs;
My use in node.js:
const axios = require("axios");
const db_client = require("../../database/connect").dbWriter;
axios.get("http://cache.boylesports.com/feeds/EUROFOOT2.json")
.then(function (response) {
console.log(response.data);
var documents = [{uri: "http://cache.boylesports.com/feeds/EUROFOOT2.json",
content: response.data,
contentType: 'application/json',
collections: ["test"]}];
db_client.documents.write({documents: documents, transform: ['js-example']}).result(
function (response) {
response.documents.forEach(function (document) {
console.log('LOADED: ' + document.uri);
});
},
function (error) {
console.log(error);
}
);
})
.catch(function (error) {
console.log(error);
});
The Client API relies on REST transforms, that do not support the same kind of splitting into multiple documents. I was hoping to say that you could use DMSDK, but it looks like that relies on the same kind of transforms. Here an example that transforms documents after uploading into the database:
http://docs.marklogic.com/guide/java/data-movement#id_22702
Looks like you would have to go against the recommendation, and create a transform that would cause side-effects by doing xdmp:document-insert calls directly.
HTH!

Passing data back from a promise resolve call

I am trying to call a function and then return some data back in the returned parameter and I am using promises but I can not get my returned data back.
I have the calls here :
fbUserInfo(recipientId,req).then(function(){
getSessionData(FB_ID).then(function(rowsJson){
console.log('%%%%%%%%' + JSON.stringify(rowsJson));
})
})
My functions are defined here
/*
* FUNCTION: getSessionData
* PURPOSE : Get the session data into global variables
*/
function getSessionData(FB_ID){
var gender, user_name;
var rowsJson = {'gender': gender, 'user_name': user_name };
console.log('START to get client data');
return new Promise((resolve,reject) => {
client.hmget(FB_ID,'gender',function(err,reply){
rowsJson.gender = reply;
console.log('^^^ gender :' + rowsJson.gender);
});
client.hmget(FB_ID,'name',function(err,reply){
rowsJson.user_name = reply;
console.log('^^^ user_name :' + rowsJson.user_name);
});
resolve(rowsJson);
}); // return
} // getSessionData
/*
* FUNCTION: fbUserInfo
* PURPOSE : Called once when displaying the user welcome message
* to get the Facebook user details an place them in the
* session if they dont already exist
*/
function fbUserInfo(id,req) {
return new Promise((resolve, reject) => {
var url = 'https://graph.facebook.com/v2.6/' + id;
console.log('^^^^ url ' + url);
const options = {
method: 'GET',
uri: url,
qs: {
fields: 'first_name,last_name,profile_pic,locale,timezone,gender',
access_token: FB_PAGE_TOKEN1
},
json: true // JSON stringifies the body automatically
}
console.log('^^^ CALL RQ');
rp(options)
.then((response) => {
console.log('Suucess' + JSON.stringify(response.gender));
var profile_pic = JSON.stringify(response.profile_pic).replace(/\"/g, "");
console.log('1. profile_pic:' + profile_pic);
// Now find the position of the 6th '/'
var startPos = nth_occurrence(profile_pic, '/', 6) + 1;
console.log('1. Start Pos: ' + startPos);
// Find the position of the next '.'
var stopPos = profile_pic.indexOf(".",startPos) ;
console.log('2. Stop Pos: ' + stopPos);
FB_ID = profile_pic.substring(startPos,stopPos);
console.log('profile_pic :' + profile_pic);
console.log('FB_ID :' + FB_ID);
var gender = JSON.stringify(response.gender).replace(/\"/g, "");
var name = JSON.stringify(response.first_name).replace(/\"/g, "");
console.log('name: ' + name);
console.log('** Set session variable');
client.exists("key",FB_ID, function (err, replies) {
if(!err && replies===1){
console.log("THE SESSION IS ALREADY PRESENT ");
}else{
console.log("THE SESSION DOES NOT EXIST");
// Now create a session from this
client.hmset(FB_ID, {
'gender': gender,
'name': name
});
resolve();
}});
})
.catch((err) => {
console.log(err)
reject();
});
})
} // fbUserInfo
What i get is :
1. profile_pic:https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/xxxxxxxxxx.jpg?oh=f43f7946f07e2bfb16fd0428da6a20e3&oe=5824B5F0
1. Start Pos: 48
2. Stop Pos: 96
profile_pic :https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/xxxxxxxxx.jpg?oh=f43f7946f07e2bfb16fd0428da6a20e3&oe=5824B5F0
FB_ID :13882352_10154200039865923_27612879517xxxxxxxx
name: Ethan
** Set session variable
^^^ gender :male
^^^ user_name :Ethan
THE SESSION DOES NOT EXIST
START to get client data
%%%%%%%%{}
You are not using callbacks inside promise the right way and your promise resolves before your client.hmget functions are finished.
You will need promise chain to get what you need, or you can quickly fix it like this:
return new Promise((resolve,reject) => {
client.hmget(FB_ID,'gender',function(err,reply){
if (err) {
return reject(err);
}
rowsJson.gender = reply;
console.log('^^^ gender :' + rowsJson.gender);
client.hmget(FB_ID,'name',function(err,reply){
if (err) {
return reject(err);
}
rowsJson.user_name = reply;
console.log('^^^ user_name :' + rowsJson.user_name);
resolve(rowsJson);
});
});
})

Categories

Resources